Core Concepts
The operator
Section titled “The operator”You are the operator. In The Matrix, the operator sits outside the simulation and controls what gets loaded into it. In jackin’, you decide:
- Which agent to load
- Which directories to mount (and whether they’re read-only)
- Which workspace configuration to use
- When to eject (stop) an agent
The operator never enters the container. You interact with jackin’s CLI and TUI from your host machine.
Agents
Section titled “Agents”An agent is an AI coding runtime (like Claude Code) running inside an isolated Docker container. Each agent:
- Has its own filesystem, network, and process space
- Runs with full permissions inside the container (
--dangerously-skip-permissions) - Can only access directories you explicitly mount
- Has Docker-in-Docker (DinD) enabled, so it can build and run Docker containers inside its own container
- Persists its state between sessions (Claude history, settings, GitHub CLI auth/config, plugins)
Agent classes
Section titled “Agent classes”An agent class is a reusable tool profile for creating agent containers. It’s defined by a GitHub repository that contains a Dockerfile and a manifest file (jackin.agent.toml). For example:
agent-smith— the default agent classthe-architect— an agent with the full Rust toolchain (used for jackin’ development)chainargos/backend-engineer— a namespaced agent for backend work in the chainargos organization
The name agent-smith is just a project-specific example. In practice, agent class names can reflect the job they are designed for:
frontend-engineerbackend-engineerinfra-operatordocs-writersecurity-reviewer
When you run jackin load agent-smith, jackin’ clones the jackin-agent-smith repository, builds a Docker image from it, and launches a container.
Think of an agent class as answering: “What kind of agent is this?”
- Which language toolchains are installed?
- Which shell setup or helper scripts are present?
- Which Claude plugins are installed?
- Which defaults should this agent start with?
One project may intentionally use several agent classes. That is not redundancy. It is how you keep the agent’s world focused. A frontend-oriented class can carry UI tooling and plugins, while a backend-oriented class can carry server tooling and database clients, even if both point at the same workspace. The smaller and more relevant that environment is, the less out-of-scope context the agent has to inspect.
Agent instances
Section titled “Agent instances”A single agent class can have multiple running instances. Each instance is a separate container with its own state. This lets you run the same agent type against different workspaces simultaneously.
The construct
Section titled “The construct”In The Matrix, the construct is the empty white space where programs are loaded before a mission. In jackin’, the construct is the shared base Docker image that every agent starts from:
projectjackin/construct:trixieThe construct provides:
| Component | Purpose |
|---|---|
| Debian Trixie | Stable base OS |
| Docker CLI + Compose | So agents can build/run containers (via DinD) |
| Git + Git LFS | Source control |
| GitHub CLI | Repository and PR operations |
| mise | Language version management (Node, Python, Go, etc.) |
| ripgrep, fd, fzf | Fast search tools |
| zsh + Oh My Zsh | Shell environment with autosuggestions |
| Starship prompt | Informative terminal prompt |
Agent repos extend the construct with their own tools. For example, an agent for Rust development would add the Rust toolchain on top of the construct.
Docker-in-Docker (DinD)
Section titled “Docker-in-Docker (DinD)”Each agent gets its own Docker daemon via a DinD sidecar container. This means agents can:
- Build Docker images (
docker build) - Run containers (
docker run) - Use Docker Compose (
docker compose up)
All within their own isolated Docker environment. The agent’s Docker daemon is completely separate from your host’s Docker daemon.
Workspaces
Section titled “Workspaces”A workspace defines how your project directories are mounted into an agent container. It specifies:
- workdir — the working directory inside the container
- mounts — which host directories to mount, where, and with what permissions
- allowed agents — optionally restrict which agent classes can use this workspace
- default agent — which agent class to auto-select when loading this workspace
Think of a workspace as answering: “Which project files can this agent see, and where do they appear in the container?”
This is why agent classes and workspaces are separate instead of being one concept.
- agent class = the environment
- workspace = the accessible files
That separation gives you two kinds of control. You can keep the same project boundary while changing the agent’s tool profile, or keep the same tool profile while changing the project boundary.
Example: one monorepo workspace can be shared by two different agent classes.
chainargos/frontend-engineersees the monorepo files and has Node, Playwright, and UI pluginschainargos/backend-engineersees the same monorepo files but has Rust, Postgres tools, and backend-specific plugins
That keeps tool and plugin scope small even when the project scope is shared.
Workspaces can be:
-
Current-directory workspace — the current directory, mounted at the same path. This is what you get with
jackin load agent-smithfrom any directory. -
Saved — named configurations stored in
~/.config/jackin/config.toml. Saved workspaces are useful when you want to reuse the same project boundary across sessions, launch from anywhere, preserve a multi-mount layout, or keep a preferred/default agent attached to that project.
Derived images
Section titled “Derived images”When you load an agent, jackin’ doesn’t use the construct image directly. Instead, it generates a derived Dockerfile that:
- Starts from the agent’s Dockerfile (which itself starts from the construct)
- Remaps the container user to match your host UID/GID
- Installs Claude Code (or another agent runtime)
- Injects the runtime entrypoint script
- Copies in Claude plugins if declared in the manifest
The resulting derived image is cached locally. Subsequent loads skip the build step unless you pass --rebuild.
State persistence
Section titled “State persistence”Agent state is persisted between sessions at ~/.jackin/data/<container-name>/. This includes:
.claude/— Claude Code session history and configuration.claude.json— Claude settings.config/gh/— GitHub CLI authentication and settings when you authenticate inside the containerplugins.json— installed Claude plugins
When you stop and restart an agent, it picks up where it left off. Use jackin purge to delete persisted state and start fresh.
Putting it all together
Section titled “Putting it all together”Here’s what happens when you run jackin load agent-smith ~/Projects/my-app:
1. Resolve agent class "agent-smith" └─ Clone/update github.com/donbeave/jackin-agent-smith
2. Validate agent repo contract └─ Check jackin.agent.toml and Dockerfile
3. Generate derived Dockerfile └─ Construct base → Agent layer → Claude install → Entrypoint
4. Build derived Docker image (cached if unchanged)
5. Create per-agent Docker network └─ jackin-agent-smith-net
6. Launch DinD sidecar container └─ jackin-agent-smith-dind on jackin-agent-smith-net
7. Launch agent container ├─ Mount ~/Projects/my-app at the same path ├─ Mount persisted state from ~/.jackin/data/ ├─ Connect to jackin-agent-smith-net ├─ Set DOCKER_HOST to DinD sidecar └─ Run Claude Code with --dangerously-skip-permissions
8. You're inside — Claude Code is ready