Coding agents are good at writing code and bad at knowing when they're wrong. I've watched an agent confidently ship a broken change, add a dependency that was published 20 hours ago, or quietly leak a secret into a commit message. So I built AI Employee — a self-hosted system that wraps AI coding agents in the same process a careful human team already uses, before anything reaches your GitHub.
The core idea
Instead of "agent writes code → you review a diff," the pipeline looks like this:
\
Task → Planner → Coder (own Git worktree) → Quick checks
→ Reviewer → UI/Security critics → Commit → Your approval → Push
\\
Every stage exists because I hit a real failure mode without it:
- Planner — reads the code, the project's handoff notes, and team memory, then writes a plan with files, acceptance criteria, and risks before any code is touched. Skipping this is how you get agents solving the wrong problem confidently.
- Quick checks — secrets, broken JSON/YAML/JS, debug leftovers, and risky new dependencies are caught with plain code, no model call. If a check fails, it goes straight back to the Coder — no wasted review cycles on obviously broken output.
- Current package versions — before planning, the npm registry is checked so new dependencies must be stable, at least 3 days old, and free of known advisories. This alone has saved me from a couple of typosquats.
- Reviewer — a separate, read-only session checks requirements, crashes, frontend/backend agreement, and tests — up to 3 rounds before it's considered a repository is a task instead.
- UI and security critics — the last line before commit, and only triggered when the change touches UI or security-sensitive files. The UI critic actually starts the app and judges real phone/desktop screenshots rather than trusting the agent's self-report.
- You approve — the Git agent writes the commit and PR, but the branch is only pushed after a human clicks approve in the dashboard.
Why sandboxing mattered more than I expected
Giving an agent a shell is giving it enough rope to do real damage, so most of the design effort went into containment rather than capability:
- Agents run inside the coding harness's sandbox (Landlock/bwrap on Linux).
- The Planner, Reviewer, critics, Git, and memory agents are read-only.
- The Coder can only write inside its own task's Git worktree — never the main checkout.
- On a server, agents run as a separate, unprivileged Linux user with no sudo, no Docker, no GitHub credentials, and no model API keys. Without that separation, sandboxing alone can't stop an agent from reusing your Git credentials.
- Secrets are blocked from memory, handoff notes, and commits by pattern-matching before anything is written.
One brain, one file
Every project, task, event, approval, cost record, and memory entry lives in a single SQLite file (using Node's built-in node:sqlite, with FTS5 for memory search). Backing up the whole system is copying one file. There's no cloud account, no external database to provision, and no vendor lock-in for something as basic as "what did my agents do last week."
Model-agnostic by design
Agents talk to models through a local gateway that adds the provider's API key, records tokens and cost, and refuses calls once a budget is hit. You can mix and match: OpenAI for planning, a local Ollama model for routine coding, Claude for the final review — whatever your cost/quality tradeoff looks like. New dependencies, model calls, and even screenshot judging can each use a different provider.
What's next
This is a developer preview — it's used daily on my own projects, but the interfaces and database schema may still shift between commits. If you're curious about the failure modes of autonomous coding agents, or just want a coding assistant you don't have to babysit line-by-line, I'd love feedback:
🔗 Repo: https://github.com/adnanahamed66772ndpc/ai-employee
It's MIT licensed and PRs are welcome — especially around the review/critic pipeline and sandbox hardening.
Top comments (0)