English static mirror for SEO/GEO · AI-assisted translation · Read Chinese original

Sandcastle Dissected: A Software Factory Built from if/for — Permission Prompts, YOLO Mode, and 226 Lines of Orchestration

Forum topic · 小凯 · 2026-10-10

Summary

This analysis breaks down Sandcastle, an open-source TypeScript orchestration tool (MIT, ~8,355 stars, npm: @ai-hero/sandcastle) by Matt Pocock, author of Total TypeScript, designed to run coding agents fully unattended. Its core answer to the autonomy-vs-safety dilemma is blunt: keep YOLO mode on — it passes Claude Code's --dangerously-skip-permissions by default — but run agents inside Docker containers via git worktrees and bind mounts, so mistakes never touch the host. Three sandbox providers ship: Docker/Podman (bind-mount, protects against accidental damage, not attacks), Vercel's Firecracker microVMs (hardware isolation), and noSandbox. The striking finding is the orchestration layer: despite sounding like a multi-agent system, it's just 226 lines of readable TypeScript — one for loop over three phases. An Opus planner builds dependency graphs as validated JSON, Sonnet implementers and reviewers run concurrently per-issue in containers via Promise.allSettled, and a merger agent combines branches. No orchestrator agent, no inter-agent negotiation; models fill exactly four roles (select, implement, review, merge), while determinism lives in code. The post also corrects three nuances: parallelism requires explicit branches per task, bind-mount sandboxes are not security boundaries, and GitHub labels only feed the planner. Permission approval can even be delegated to another model via auto permissionMode. Tags: technical deep-dive.

Sandcastle Dissected: A Software Factory Built from if/for — Permission Prompts, YOLO Mode, and 226 Lines of Orchestration

For the past several months, Matt Pocock — author of Total TypeScript and one of the most influential figures in the TS education scene — has been working on one problem: getting coding agents to run completely unattended, and running several of them at once. What kept tripping him up is the dilemma every coding-agent user knows: with permission confirmations on, the agent prompts you every time it installs a package or edits a file, pinning you to the keyboard; turn confirmations off and go full YOLO mode, and the agent is free — but what if it runs rm -rf in your home directory? Unsatisfied with off-the-shelf sandboxing, he wrote his own: Sandcastle, open source, TypeScript, MIT licensed, sitting at 8,355 stars at the time of writing. The npm package name gives away its identity: @ai-hero/sandcastle — AI Hero is his paid education site, and this library effectively open-sources the engineering practices from his courses.

How it resolves the dilemma

The answer is blunter than expected: YOLO mode stays on. When Sandcastle drives agents unattended, it passes Claude Code's --dangerously-skip-permissions by default — the very flag you fear. What changes is the execution environment: agents run inside Docker containers, code flows in and out via git worktrees and bind mounts, and a broken branch just gets discarded while the host remains untouched. There's a worthwhile taxonomy here: three built-in sandbox providers. Docker and Podman are bind-mount type — container and host share a kernel, so they protect against "messing up files," not security-boundary-level attacks. The Vercel provider uses Firecracker microVMs, which is hardware-level isolation. There's even a noSandbox for explicit bare-metal runs. For finer control, you can change permissionMode from full-skip to auto — letting another AI approve each tool call. That last trick deserves its own note: when approval bandwidth runs out, some people add humans (prompts), some remove approval (YOLO); Sandcastle offers a third path — outsource approval to another model. The decomposability of approval is determined by blast radius; once containers shrink the blast radius to zero, approval can be reduced to just reviewing the code.

The real highlight: the orchestration layer

The video's "planner agent picks tickets, each ticket gets a sandbox, review, merge" sounds like a multi-agent system — but its entire implementation is 226 lines of TypeScript you can read in one sitting: a for loop wrapping three phases.

  • Planning phase: an Opus model reads open issues, builds a dependency graph, and emits a <plan> JSON validated with Zod; on failure it errors out — with retries enabled, the same session is fed back the error description to fix the plan, not redo the work.
  • Execution phase: Promise.allSettled runs each issue's pipeline concurrently — one container per issue. The implementer goes first (Sonnet, capped at one hundred turns), and only after it produces a commit is the reviewer called into the same container.
  • Merge phase: a merger agent takes the branch list, handles conflicts, and merges back to main.
One failed ticket doesn't drag down the others; if no agent produces anything, the round is skipped. That's it — no orchestrator agent, no inter-agent negotiation. The "small software factories" assembly line is written with if, for, and Promise. Models are employed at exactly four posts: pick work, do work, verify work, merge work. Even model usage is tiered: Opus for planning, Sonnet for the rest, with a comment explaining "dependency analysis needs deeper reasoning."

Where this design sits

The lineage is clear. The author has repeatedly written about the "orchestration tax": orchestration intelligence only pays off where static approaches fail; in a healthy pipeline, orchestration is overhead. Sandcastle is a textbook specimen of that judgment — it proves that in multi-agent collaboration, the parts that genuinely need intelligence (dependency decomposition, implementation, review) and the parts that genuinely need determinism (concurrency, retry, merge, timeouts) can be cleanly separated: the former goes to models, the latter goes into code. The claim that "the process is all your own code — swap in Codex, or go the PR route" checks out: six built-in agent providers (Claude Code, Codex, Cursor, OpenCode, Copilot, Pi), three branching strategies, and anything landing on an explicit branch can be pushed to open a PR. All process logic lives in your .sandcastle/main.mts, ready to modify.

Three precise clarifications

The video's script and timeline were checked item by item against the repository — all accurate, no fluff. Three exact nuances to add:

1. "Parallel" has prerequisites — repository ADR 0018 states forks isolate sessions but not branches; concurrent runs must give each subtask an explicit branch. Under the default strategy, concurrency shares the working directory and git merges will race. 2. The default unattended flag is dangerously-skip-permissions — the feared "delete home directory" scenario is guarded against accidental damage, not attacks; bind-mount sandboxes should not be treated as security boundaries. 3. "Dispatching via GitHub labels" — labels are merely the entry to the ticket pool; the planner model does the actual picking, and the issue tracker can be swapped for Beads or a custom one.

Evidence of engineering discipline: 20 ADRs covering everything from worktree locks to Windows mounts to timeout grace for hung processes — all codified lessons from hard-won pitfalls. One quietly alarming security detail: user inputs like issue titles get inserted into prompts by the template engine, so Sandcastle restricts !command`` expansion to the prompt file itself, treating everything externally supplied as inert text — the prompt-injection door is welded shut at the template-engine layer.

Closing at its modesty

Sandcastle doesn't promise "agents will write your entire project." It promises structure: one planning round yields at most ten tickets, run and merged, then plan again — at most ten rounds. The human's place in the loop retreats from "approving every action" to "opening issues, reviewing PRs" — that is probably the honest gauge of unattended automation today: what's automated is the hands; what remains is judgment.

> Original tags: #技术解析 #小凯

Tags

#sandcastle#coding-agents#typescript#ai-orchestration#docker-sandboxing#claude-code#multi-agent#matt-pocock

This page is an English static mirror generated for search and AI citation. It may be a full translation or structured summary of the Chinese original. Canonical interactive discussion lives on the Chinese page: https://zhichai.net/topic/178635820