The cell
One container per card.
- Non-root, no new privileges, minimal capabilities
- No repository token
- A one-run nonce instead of your model key
- Secrets in RAM, never in argv or on disk
Taskcell is a self-hosted software factory. Every card is built in its own sealed sandbox cell, has to pass your gates and a review, and lands as a pull request. You merge.
Swap the source: GitHub, GitLab, Linear or a GitHub Projects board. Swap the engine: Claude Code, Codex, Cursor or a model through OpenRouter. The line stays the same.
How it works
Six stations, the same for every card. You set the trigger and you merge; Taskcell does the toil in between.
Label an issue on GitHub, GitLab or Linear, or move a card on a GitHub Projects board. A card too vague to build goes back as needs info before any model runs.
A planner reads the code and writes a tech spec with acceptance criteria. It is posted on the issue, and you get a window to read it before the build starts.
The agent builds the card in a Docker container of its own: non-root, no new privileges, a minimal capability set, no repository token, one git worktree per card.
Your verify script runs and the host scans the diff for secrets. A red gate sends the card back for a repair, at most twice; the second can run on a stronger model.
A reviewer reads the diff in a fresh context and fixes what it finds. Give it a second model, for example Codex reviewing Claude's work.
The host pushes the branch and opens the PR: ready for review when every gate passed, a draft when one did not. On GitHub, your review comments go back for a revision. You merge.
Swappable parts
The source and the engine are plug-in parts on the line. Change either one with a flag; the cell, the gates and the review stay the same.
Where cards come from.
--github owner/repo#nPull requests on GitHub, with revisions from your review comments.--source projectMoving a card to Todo starts the build.--source gitlabgitlab.com or self-hosted, through glab. Merge requests instead of PRs.--linear TES-1Through the linear CLI. A workflow state is the trigger.Who writes the code, on the plan or keys you already have.
--provider claudeThe default. A Claude subscription token or an API key.--provider codexAn OpenAI API key, or a ChatGPT plan.--provider cursorThe Cursor CLI, added to the sandbox image on request.--provider openrouterOther models through Anthropic-compatible endpoints.Claude builds, Codex reviews
vanguard run --github you/app#42 --repo ../app --provider claude --review-provider codex
Security
It reads text anyone can write: issues, repository files, dependencies. So it works inside a cell, and everything that can do damage stays outside.
Your machine or server. Only it holds what can do damage.
One container per card.
With the egress allowlist on. Without it, the cell's network is open.
A Docker container, non-root, with no-new-privileges and every capability dropped except the three it needs to own files (CHOWN, FOWNER, DAC_OVERRIDE). No GitHub or GitLab token inside. Secrets arrive as an in-RAM file, never in argv or docker inspect.
On a Linear task the cell gets the Linear key, to read the issue.
The LLM proxy, a sidecar on the host, holds the real model key. The agent gets a nonce that is useless after the run.
CLI: --llm-proxy, for Claude, Codex on an API key, z.ai and OpenRouter. The Hub always uses it for those. Codex on a ChatGPT plan, Cursor and Meridian still put their key in the cell, and the Hub warns you.
The cell sits on an internal Docker network whose only way out is a proxy that tunnels allowlisted hosts. A process that ignores the proxy settings has no route out.
--egress, and implied by --llm-proxy.
The host scans the diff before anything leaves. A hit pushes nothing.
Agent edits to .github/workflows, .github/actions, .gitlab-ci.yml and .gitlab/ YAML are dropped on the way out of the cell, and the PR lists them under Not included.
It binds to 127.0.0.1 by default, rejects unknown Host headers against DNS rebinding and needs a token minted at each launch.
It has no login yet: on a server, put it behind Tailscale or an authenticating proxy.
No third-party audit yet. The boundaries are written down in the README and in a self-hosted security review in the repository. Found a hole? Report it privately; you get an answer within 7 days.
Self-host
Taskcell runs where Node 24 and Docker run: a laptop, a home server, a VPS. It uses the AI subscription or API keys you already pay for.
Install from source
git clone https://github.com/spietrza/taskcell.git
cd taskcell
pnpm install && pnpm build
docker/build.sh # the sandbox image
pnpm link --global # puts vanguard on your PATH
Also needed: gh for GitHub, glab for GitLab or the linear CLI for Linear.
Run a single issue end to end, with the key held by the LLM proxy.
# token from: claude setup-token
export CLAUDE_CODE_OAUTH_TOKEN=…
vanguard run --github you/app#42 \
--repo ../app --llm-proxy
Or vanguard watch to keep picking up labelled issues on its own.
Projects, the task board with New Run, the fleet, and every run's record, in a browser.
pnpm build:ui
vanguard hub --repo ../app
# http://127.0.0.1:7777
A Docker image for a VPS or a home server, Coolify or plain Compose.
docker build -f docker/hub.Dockerfile \
-t vanguard-hub .
Behind Tailscale or an authenticating proxy, never a published port. Mounting the Docker socket gives the Hub root on that host.
The Hub
vanguard hub shows your projects, the task board and the cost of every run. The live factory floor is coming to it; this is how it will look.
Preview with sample data. Projects, the board and cost per run are in the Hub today; the floor panel is not yet.
| Card | Models | Cache | Cost |
|---|---|---|---|
| TC-44 | Claude, Codex review | 97% | $0.84 |
| TC-45 | Claude, Codex review | 98% | $0.61 |
| TC-43 | Claude, 1 repair | 96% | $1.27 |
| TC-42 | Codex, Claude review | 95% | $0.93 |
| TC-41 | Claude, Codex review | 98% | $0.58 |
FAQ
Taskcell is open source under the MIT license. You pay your model provider, through the plan or the API keys you already have. Each run records its tokens, cache use and cost, and a per-run budget cap stops a run that gets too expensive (on the engines that run the Claude CLI; not yet on Codex or Cursor).
No. It opens pull requests and a person merges them. A failed gate makes the PR a draft rather than hiding the failure.
No. Claude Code runs on a Claude subscription token or an API key; Codex on an OpenAI key or a ChatGPT plan; Cursor, OpenRouter and z.ai on their own keys. A run that uses only Codex or Cursor needs no Anthropic credential.
Your repository is checked out on your host and the agent works on it inside the cell. What the agent sends to its model provider goes there, as with any coding agent. One opt-in feature, the difficulty probe, sends issue text to a decision-model endpoint; it is off unless you turn it on.
The card goes back for a repair, at most twice. If it is still red, the PR opens as a draft with a verify-failed label, so you see the failure instead of a green-looking PR.
Taskcell used to be called Vanguard. The CLI, the VANGUARD_* variables, the vanguard:* labels and the .vanguard/ folder keep that name for now; the old repository URL redirects to the new one.
Yes. Reusable GitHub Actions workflows run the same factory when you label an issue, and the Hub can import those runs' records to show them.
Not by a third party. The security model and its limits are documented in the repository, and vulnerabilities can be reported privately through GitHub.
Put one card through it this week.
Get it on GitHubOpen source, MIT. The command is still vanguard.