Simple Task Loop
MIT↓ 2 downloadsv1.0.0
A single Claude Code agent that works through a TASKS.md checklist one item at a time, committing each change, until every task is done. The minimal Sandcastle teaching example.
Topology
Disclosures
Everything below runs on your machine or inside the sandbox when you use this workflow. Mismatches between these declarations and the actual code block publishing.
Host hooks
Commands executed on YOUR host machine by Sandcastle lifecycle hooks.
None declared.
Sandbox hooks
Commands executed inside the sandbox container.
None declared.
Network access
None. The agent operates only on the local repository inside the sandbox.
Shell expansion
No shell-expansion blocks in prompt files.
Files
Diff vs the stock Sandcastle 0.12.0 template Dockerfile — green lines were added by the author, red lines were removed from stock.
+# Sandbox image for the Simple Task Loop workflow.+# Mirrors the stock Sandcastle template: Node 22, git, and the Claude Code CLI,+# running as a non-root `agent` user.FROM node:22-bookworm# System dependencies.RUN apt-get update && apt-get install -y --no-install-recommends \git \curl \jq \ca-certificates \&& rm -rf /var/lib/apt/lists/*# Claude Code CLI (the agent runtime).RUN npm install -g @anthropic-ai/claude-code# Non-root agent user. `sandcastle docker build-image` aligns AGENT_UID/GID to# the host user via --build-arg to avoid permission errors on bind mounts.ARG AGENT_UID=1000ARG AGENT_GID=1000RUN groupadd --gid ${AGENT_GID} agent \&& useradd --uid ${AGENT_UID} --gid ${AGENT_GID} --create-home --shell /bin/bash agentUSER agentWORKDIR /workspace
Show full Dockerfile (highlighted)
# Sandbox image for the Simple Task Loop workflow.
# Mirrors the stock Sandcastle template: Node 22, git, and the Claude Code CLI,
# running as a non-root `agent` user.
FROM node:22-bookworm
# System dependencies.
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
curl \
jq \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Claude Code CLI (the agent runtime).
RUN npm install -g @anthropic-ai/claude-code
# Non-root agent user. `sandcastle docker build-image` aligns AGENT_UID/GID to
# the host user via --build-arg to avoid permission errors on bind mounts.
ARG AGENT_UID=1000
ARG AGENT_GID=1000
RUN groupadd --gid ${AGENT_GID} agent \
&& useradd --uid ${AGENT_UID} --gid ${AGENT_GID} --create-home --shell /bin/bash agent
USER agent
WORKDIR /workspace
# Auth for the Claude Code agent.
# Run `claude setup-token` on your host to generate a token, then paste it here
# in your local .sandcastle/.env (never commit the real .env).
CLAUDE_CODE_OAUTH_TOKEN=
import { run, claudeCode } from "@ai-hero/sandcastle";
import { docker } from "@ai-hero/sandcastle/sandboxes/docker";
// The simplest Sandcastle workflow: a single agent working a task loop.
// Default branch strategy for a bind-mount provider (docker) is `head`, so
// commits land directly on the current branch — no worktree, no merge step.
const result = await run({
name: "simple-loop",
agent: claudeCode("claude-opus-4-8"),
sandbox: docker(),
promptFile: ".sandcastle/prompt.md",
maxIterations: 10,
completionSignal: "<promise>COMPLETE</promise>",
});
console.log(`Ran ${result.iterations.length} iteration(s).`);
console.log(`Created ${result.commits.length} commit(s) on ${result.branch}.`);
Task loop
You are an autonomous coding agent working inside this repository.
Open TASKS.md in the repository root. It contains a checklist of small,
independent tasks written as GitHub-style checkboxes.
Work through the checklist one task at a time:
- Pick the first unchecked task.
- Implement it with a single, focused commit.
- Tick its checkbox in
TASKS.md. - Continue with the next unchecked task.
Keep every change minimal and self-contained. Do not refactor unrelated code and do not combine multiple tasks into one commit.
When every task in TASKS.md is checked off, output the exact line
<promise>COMPLETE</promise> and stop.
README
Simple Task Loop
The smallest useful Sandcastle workflow: one Claude Code agent, one Docker sandbox, no hooks, no network access.
What it does
The agent reads a TASKS.md checklist from your repository root and works
through it one item at a time. For each unchecked task it makes a small,
focused commit, ticks the box, and moves on. When every task is checked off it
emits <promise>COMPLETE</promise> and the run stops early instead of burning
the remaining iterations.
How it works
main.ts calls run() once with maxIterations: 10. The default head
branch strategy means commits land directly on your current branch through the
Docker bind mount — there is no worktree indirection and nothing to merge.
Requirements
Set CLAUDE_CODE_OAUTH_TOKEN in .sandcastle/.env (run claude setup-token
on your host). Build the image once with
npx @ai-hero/sandcastle docker build-image, then run it with
npx tsx .sandcastle/main.ts.
This package is intentionally minimal — read it first if you are learning how Castellan packages and Sandcastle orchestration files fit together.