This is the Claude Code config stack I've been using and iterating on. It makes Claude work like an autonomous, senior engineering team-of-one — it plans, implements, verifies, and reviews its own work for correctness and security before calling anything done.
It ships as a Claude Code plugin, cas, served from this repo's own marketplace: install it, run /cas:setup once in your repo, and Claude Code starts following the loop below. Sharing it in case it's useful to someone else — it's still evolving.
Claude runs inside an isolation boundary — an OS-level sandbox, or a disposable VM/container — where it can work without stopping for approval, while the host outside the boundary stays protected. Within that boundary, permissions are not what keeps the output good — the mandatory review gate is. Every task ends with a parallel cas:code-reviewer + cas:security-reviewer pass, and the work is not "done" until both come back clean.
Isolation protects the host. The review gate protects the codebase. Two different jobs.
The repo root is the plugin (and its own marketplace):
.
├── .claude-plugin/
│ ├── plugin.json # the `cas` plugin manifest
│ └── marketplace.json # this repo is its own marketplace: `claude-agentic-stack`
├── MANUAL.md # operating manual — every session is told to read it by the hook below
├── hooks/
│ ├── hooks.json # SessionStart hook (the only hook)
│ └── session-start.sh # prints a short "read MANUAL.md first" directive into context
├── commands/
│ ├── build.md → /cas:build # the full loop in precision posture
│ ├── prototype.md → /cas:prototype # vision → app: iterate across milestones
│ ├── mockup.md → /cas:mockup # design checkpoint: variants → your pick → .agentic/design.md
│ ├── resume.md → /cas:resume # re-enter an interrupted run from .agentic/ state
│ ├── verify.md → /cas:verify # build + lint + test + runtime smoke gate
│ ├── review.md → /cas:review # reviewers in parallel → one report
│ ├── sync.md → /cas:sync # bring branch up to date with base; re-gate (local)
│ ├── ship.md → /cas:ship # finalize: gate + commit + sync + push + PR
│ └── setup.md → /cas:setup # one-time repo setup: isolation profile, guards, registration
├── agents/ # dispatched as cas:<name>
│ ├── product-designer.md # kickoff Q&A + lean spec + mockup variants; gap review (read-only)
│ ├── planner.md # decomposes a task → plan + tests + surface impact (read-only)
│ ├── test-engineer.md # writes & runs meaningful unit tests
│ ├── e2e-tester.md # boots the app on the VM, smokes it, screenshots it
│ ├── code-reviewer.md # reviews diff: correctness / quality / reuse (read-only)
│ ├── security-reviewer.md # audits diff against a threat checklist (read-only)
│ └── ux-reviewer.md # critiques the rendered UI vs spec + design contract (read-only)
├── skills/
│ └── frontend-design/ # vendored Anthropic skill (Apache-2.0) → cas:frontend-design
└── profiles/ # permission profiles — a plugin can't ship settings, so /cas:setup installs one
├── settings.ssh-sandbox.json # DEFAULT: limited host, free VM reached over SSH
├── settings.bash-sandbox.json # mac/Linux/WSL2, no separate VM: built-in OS Bash sandbox
└── settings.vm-bypass.json # when Claude Code runs INSIDE a disposable VM/container
claude plugin marketplace add grappeq/claude-agentic-stack # once per machine
cd /path/to/your-repo
claude plugin install cas@claude-agentic-stack --scope project # enable it for this repo
claude # start a session there ……then, inside the session, run /cas:setup. A plugin can carry commands, agents, skills, and hooks — but not a permission policy — so /cas:setup installs the rest into your repo: it asks which isolation profile fits your setup (see Isolation model below) and writes it to .claude/settings.json (merging with what's there, showing the diff first), probes the sandbox, adds the .agentic/ ignore guard (run evidence — screenshots, mockups, progress logs — can contain secrets or PII and must never be committed; the stack also drops a .agentic/.gitignore of * on first run as a backstop), writes a short CLAUDE.md pointer if you have none (if you do, it prints the lines to add), and registers the marketplace + plugin in .claude/settings.json so collaborators who trust the folder get it too. Restart the session afterwards — permission settings are read at startup.
Install scope: --scope project records the plugin in the repo's .claude/settings.json (shared via version control); --scope user enables it in every repo on the machine — use that on a CI runner (a headless claude -p "/cas:build …" needs the plugin installed on the runner). Confirm what loaded with claude plugin details cas@claude-agentic-stack; in a session, type /cas: to see the commands.
The same machinery runs in two modes — pick by the work:
/cas:build <task>— precision. Changing an existing system: smallest viable change, reuse first, match conventions. A single pass with an inner convergence loop./cas:prototype <vision>— prototype. Turning a broad vision into a working app: a brief kickoff interview (a few questions plus one design pick) pins down the need, then it runs autonomously — making the product and UX calls itself (recording assumptions) and iterating across milestones until the vision is met. Built for long, unattended runs.
/cas:build <task>
│ understand ── reuse first; Explore agent for broad search
│ plan ── cas:planner agent (non-trivial) → durable target: .agentic/task.md
│ mockup† ── /cas:mockup when the plan reports a new surface → .agentic/design.md
│ implement ── edit on host; smallest viable change, match conventions
│ /cas:verify ── on the VM: build + lint + tests + RUNTIME SMOKE → green
│ (cas:test-engineer adds units · cas:e2e-tester boots & drives the app)
│ REVIEW GATE ── cas:code-reviewer ‖ cas:security-reviewer ‖ cas:ux-reviewer* (parallel, read-only)
│ resolve ── fix Critical/High, re-verify, re-review changed dimensions
└─ report ── auto-commit on green (work branch) ──► /cas:ship to push / open a PR
* cas:ux-reviewer only when the diff touches UI
† only for a new screen / endpoint / command / schema
/cas:prototype <vision>
│ KICKOFF (interactive) ── cas:product-designer proposes the few high-leverage
│ questions → you answer (AskUserQuestion) → lean .agentic/spec.md written
│ → spec checkpoint (one confirm) → /cas:mockup: pick a design for M1's key
│ surfaces → .agentic/design.md frozen → gate closes, no more questions
│ (headless: no Q&A or pick — defaults; /cas:mockup still runs, design=auto)
│ ┌─ per milestone, autonomous ───────────────────────────────────┐
│ │ plan → mockup (auto, new surfaces) → implement → /cas:verify │
│ │ REVIEW GATE: code ‖ security ‖ ux* → resolve until clean │
│ │ (stuck? circuit-breaker: 3 tries, then route around/stop) │
│ │ GAP REVIEW vs spec + design: ITERATE · ADVANCE · DONE · ASK │
│ │ checkpoint → .agentic/progress.md (survives compaction) │
│ └───────────────────────────────────────────────────────────────┘
│ ⟲ until spec met, round budget spent (default 3), or ASK
└─ commit each milestone on green · report ──► /cas:ship to push / open a PR
* ux only for milestones that render UI
The orchestrator is the main Claude thread — and the one that writes the code. The agents are isolated-context leaf workers that find problems and assess progress; the orchestrator implements, fixes, and coordinates. There's deliberately no "software-engineer" agent: production implementation wants the full context the main thread already holds — the plan, the spec, the live review findings — and stays coupled to the fix loop, whereas search, review, and test-authoring are the bounded jobs that actually benefit from a clean, isolated context. (Subagents also can't spawn subagents, so coordination lives in the main thread regardless.)
Work converges through three loops — it helps to name them:
- L1 — Convergence loop (inner).
resolve → re-verify → re-reviewuntil smoke is green and code / security / ux are clean. This is reactive: it drives the work to a correctness bar by fixing defects. But it never makes the product better — only correct. A blank-but-valid app passes L1. - L2 — Improvement loop (outer). Build → critique against the vision → build the next increment → repeat. This is generative: it makes the thing more complete and more polished over successive rounds. It's the half that takes a broad vision and improves on it itself, rather than only making a given change correct — and it's what
/cas:prototypeadds on top of L1. - L3 — Human iteration. You read the report (and screenshots) and send the next prompt, edit
.agentic/spec.mdor.agentic/design.mdto steer the next run, or/cas:resumeto continue an interrupted one. Always there.
So /cas:build is mostly L1; /cas:prototype is L2 wrapping L1, then back to you (L3).
- Prototype from a vision:
/cas:prototype a habit tracker with streaks and weekly stats— a few kickoff questions and one design pick, then it designs, builds, iterates across milestones, and screenshots it autonomously. - Precision change:
/cas:build add rate limiting to the login endpoint— when the plan reports a new user-facing surface (a screen, endpoint, command, or schema) it stops once for a design pick;design=autotakes the recommended default,design=skipbypasses it. - Design checkpoint on its own:
/cas:mockup the settings screen— 2–3 variants (web artboards, a CLI storyboard, API examples, a schema, or an architecture spine, by medium), your pick, frozen as a contract in.agentic/design.mdthat reviewers hold the build to. - Resume an interrupted run:
/cas:resume— reloads the.agentic/state (task/spec + progress), reconciles it with the repo, and re-enters the loop where it left off. Works after a crash, a closed session, or when you deliberately restart with a fresh context instead of grinding on a degraded one. Pass steering as arguments:/cas:resume drop the CSV export, ship the rest. - Just review what you have:
/cas:review(or/cas:review staged) - Just run the gate:
/cas:verify - Set up a repo:
/cas:setup— once per repo; idempotent, so re-run it after changing the sandbox alias or profile. - Auto-commit: the loop commits on green automatically, on a work branch — you don't run anything.
- Sync with the base branch:
/cas:syncbrings your work branch up to date with master — resolving any conflicts safely and re-running the gate — local only, never pushes./cas:shipruns it automatically first, but you can also run it mid-work. - Publish when ready:
/cas:shipre-confirms the gate, curates the commit, syncs with the base, then pushes and opens a PR — invoking it (the model can't self-trigger it) is your go-ahead to publish. e.g./cas:ship feat: add login rate limiting. - Headless / CI:
claude -p "/cas:build add rate limiting to the login endpoint"(the plugin must be installed on the runner —--scope user— and the sandbox VM reachable viassh sandbox; any design pick takes the recommended default) - Deeper one-off audits: the built-in
/code-reviewand/security-reviewskills complement the in-loop gate.
The agent runs on a limited host and offloads real execution to an isolated sandbox, so it can act freely without endangering the host. /cas:setup asks which profile matches how your sandbox is reached (or pass profile=ssh|bash|vm) and installs it into .claude/settings.json. deny rules are enforced from every scope and even override allow, so the host floor holds regardless of mode. The ssh and bash profiles also allow one read outside the workspace — the plugin's own MANUAL.md in Claude Code's plugin cache (~/.claude/plugins/cache/claude-agentic-stack/cas/*/MANUAL.md) — because the SessionStart hook has every session read it first; without that rule the read prompts each session (and is denied headless). Adjust the path if you set CLAUDE_CONFIG_DIR, load the plugin with --plugin-dir, or install it from a fork or a marketplace under another name — the rule keys on the marketplace name claude-agentic-stack, so it also covers any marketplace you add under that name.
| Your setup | Profile | Host vs. sandbox |
|---|---|---|
| Claude Code on a host that SSHes into a separate sandbox VM | profile=ssh (default) |
Host: edit + git + sync only; dangerous ops and secret reads (~/.ssh, ~/.aws, .env) denied. VM (ssh sandbox …): unrestricted — every build/test/install runs there. |
| Claude Code on macOS / Linux / WSL2, no separate VM | profile=bash |
The built-in OS Bash sandbox confines bash + child processes to the workspace, denies credentials, allowlists network; auto-allow = no prompts inside the boundary. |
| Claude Code runs inside a disposable VM / container / sandbox-runtime | profile=vm |
The VM/container is the wall; bypassPermissions is fine inside it; your real host is unreachable. Required for fully unattended --dangerously-skip-permissions. |
- Provision a disposable Linux VM with the toolchains your projects need (node, python, go, …).
- Add an SSH alias named
sandboxto~/.ssh/configon the host:The profile's allow-ruleHost sandbox HostName <your-vm-ip> User dev IdentityFile ~/.ssh/sandbox_keyBash(ssh sandbox *)keys off this exact alias. Keepsandboxunless you have to:/cas:setup alias=<name>rewrites the allow-rules and records the alias in yourCLAUDE.md, but the commands' own examples still sayssh sandbox. - Pick the remote working directory with
/cas:setup dir=<path>(default~/agentic-workspace); it lands inSANDBOX_REMOTE_DIRin.claude/settings.json. - Make sure
rsyncis available on host and VM for fast syncs (scp -ris the fallback). - For frontend e2e — the runtime smoke that boots a browser and screenshots the UI — install a headless browser on the VM:
npx playwright install --with-deps chromium. Without it,/cas:verify's runtime smoke degrades gracefully to an HTTP-level check andcas:ux-reviewerreports that no screenshots were available.
/cas:setup probes each of these (VM reachable, rsync on both ends, toolchains for the manifests it finds, headless Chromium) and prints a ✓/✗ line with the fix for anything missing. Now /cas:verify syncs the working tree to the VM and runs build/lint/test there; the host only edits and commits. Edits happen on the host (Claude's Read/Edit/Write), execution happens on the VM (ssh sandbox …).
Why SSH and not the OS Bash sandbox here? The built-in Bash sandbox doesn't run on native Windows, and it only confines Bash (not MCP/hooks). A real VM reached over SSH gives a stronger, OS-independent boundary and matches a "controller host + disposable worker" topology. The other two profiles are there if your setup differs.
Plugin files live in Claude Code's plugin cache and are replaced on claude plugin update, so don't edit them in place. Per-repo tuning goes in your own CLAUDE.md — the operating manual is loaded alongside it and defers to it for project specifics:
- Sandbox target — a non-default SSH alias or remote dir: pass
alias=/dir=to/cas:setup(it keeps the allow-rules andSANDBOX_REMOTE_DIRin sync and records them in yourCLAUDE.md). - Security checklist — add your domain's threats (payment flows, PII handling, tenancy isolation) to your
CLAUDE.md;cas:security-reviewerextends its checklist per project. - Verify gate / runtime smoke — state your exact build, lint, test, and boot commands and the user flows the smoke should drive in your
CLAUDE.md;/cas:verifyandcas:e2e-testerprefer the project's own scripts over their generic detection. - Iteration depth — pass
rounds=Nto/cas:prototype, or set a default in yourCLAUDE.md. - Design checkpoint — pass
design=ask|auto|skipandfidelity=wireframe|styledto/cas:build,/cas:prototype, or/cas:mockupper run. - Run artifacts — a
/cas:buildrun writes its task, acceptance criteria, and live plan checklist to.agentic/task.md; a/cas:prototyperun writes its frozen vision to.agentic/spec.mdand live progress to.agentic/progress.md;/cas:mockupwrites the approved design contract to.agentic/design.mdwith the mockups under.agentic/design/(all git-ignored). Read them to see where an autonomous run is, edit them between runs to redirect it, or/cas:resumeto continue it. - Everything else — the Definition of Done, the mockup medium table, the reviewers' severities, agent models (
cas:code-reviewerruns onsonnetfor speed; the restinherityour session model for rigor) — fork the repo, edit, and point your marketplace at the fork:claude plugin marketplace add <you>/claude-agentic-stack. To develop the stack itself, add your checkout as a local marketplace (claude plugin marketplace add /path/to/checkout) and install from it.
- Two-layer security model — isolation (the sandbox VM / OS sandbox) protects the host; the review gate is semantic and protects the codebase. Neither substitutes for the other, and the stack ships both.
- Review-agents enforcement, not blocking hooks — the gate is semantic (AI review) and lives in the workflow, so it adapts to any language without per-repo hook scripts. The plugin's only hook is the
SessionStartone that points each session at the manual. - Read-only reviewers — reviewers can't edit, so they can never silently "fix and pass" their own findings. Clean find/fix separation. This now extends to UX:
cas:ux-reviewercritiques the rendered UI with fresh eyes instead of the builder grading its own design. - Runtime smoke, not just unit tests — the gate boots and drives the assembled app (browser / API / CLI), so "it compiles" can't masquerade as "it works". The screenshots double as e2e evidence and as the input to independent UX review.
- Generative + evaluative symmetry — the stack pairs a maker and a critic for each concern: code (
cas:planner→cas:code-reviewer/cas:security-reviewer) product/UX (cas:product-designer→cas:ux-reviewer), and now design (cas:product-designerDESIGN: PROPOSE →cas:ux-reviewerdesign-fidelity check, orcas:e2e-testergolden assertions for CLI/API surfaces), withcas:product-designeralso closing the loop by gap-checking the build against its own spec and the approved design. - The orchestrator is the implementer — there's no dedicated "coder" agent, by design. The subagents are the roles that gain from an isolated context (broad search, adversarial review, bounded test-authoring against a frozen diff); open-ended production implementation instead wants the orchestrator's full context and lives in the resolve loop where it fixes what the reviewers find. Delegating it would break the find/fix separation and add lossy clean-context round-trips on every fix.
- Commit vs. publish — the agent auto-commits on a work branch once the gate is green (local, reversible, no prompt), but publishing — push, PR, release — stays human-gated via
/cas:ship. The boundary is external visibility, not the git verb. - Built for long autonomous runs —
/cas:prototypefront-loads a brief kickoff interview (spec + one design pick), then runs hands-off. The frozen vision (.agentic/spec.md) and a progress log (.agentic/progress.md) are durable, so a run survives context compaction; a circuit-breaker caps repeated failed fixes (3 tries) so a stuck check can't burn the session.cas:ux-reviewercompares screenshots round-over-round to catch UI regressions. - Interruptible by design — every run keeps a durable target on disk (
task.mdfor/cas:build,spec.md+progress.mdfor/cas:prototype,design.mdfor either), so/cas:resumecan re-enter it from a fresh session: reload the state, reconcile it against git (the repo wins on code facts), re-verify, continue. Deliberately restarting with a clean context beats grinding on a degraded one — the useful half of the "Ralph loop" pattern, without the bash loop. Starting a new run surfaces any unfinished one instead of silently overwriting its state. - Design before code, by medium — the design checkpoint (
/cas:mockup) exists because the cheapest moment to redirect a design is before it is built, and the loop otherwise shows you a design only after a milestone is built, verified, and reviewed. It is deliberately about the surface a user or caller experiences, not about pixels: web artboards, a CLI storyboard, API request/response examples, a schema, or an architecture spine — so it works for a backend service as well as a web app, and for text media the approved examples become the smoke assertions./cas:buildonly runs it when the plan reports a genuinely new surface (a change to an existing screen follows its design system), and/cas:prototypeasks once at kickoff and defaults later surfaces, so the "brief kickoff, then hands-off" promise holds. Web mockups are static HTML artboards rendered on the sandbox VM with Playwright; when the session has the built-indesignskill's canvas (/design; a research preview — claude.ai login only, not API-key, Bedrock, or Vertex) it doubles as a nicer, hand-tweakable preview, but the stack never depends on it: the HTML + PNG under.agentic/design/are the evidence the read-only reviewers can actually open. - Why three target files —
task.md,spec.md, anddesign.mdare the same pattern (durable target + live state) split by authority, not structure. The spec is a user-confirmed contract: drafted from your interview answers, approved at the spec checkpoint, then frozen — so a long unsupervised run converges on a target the agent can't quietly move; only the user edits it. The task file is the agent's own working restatement of a short, supervised change — continuously edited, never blessed, folding target and progress into one file because a single-milestone run doesn't need the split. One shared filename would let agent notes wear contract-grade authority (a misread task would be enshrined as if confirmed). The filename is the permission model:spec.md= the agent never edits it;task.md= the agent keeps it live.design.mdis a second user-confirmed contract — a concrete artifact (mockup, transcript, examples) rather than a vision outline — kept separate fromspec.mdbecause it is approved at a different moment, per surface, and can be re-run with/cas:mockupwithout reopening the vision; the same rule applies: only/cas:mockupwrites it, and each section records whether the user picked it or it was defaulted (assumption-grade, not contract-grade). - Warm sandbox, cold path removed — the loop kicks off the VM dependency install during the implement phase, so it finishes in the background instead of sitting cold on the critical path at
/cas:verify. Ecosystem-agnostic (it uses whatever install the manifest implies) and best-effort —/cas:verifystill runs the authoritative install, so the gate is unchanged; it only reclaims latency. - No required MCP / Node / jq — the stack is pure markdown and JSON. The hook is a short POSIX
shscript;/cas:setup's settings merge is done by the model with the diff shown before writing, so nothing needs a JSON tool on the host. - Packaged as a plugin — a plugin can't ship a
CLAUDE.mdor a permission policy, which is exactly the two things this stack is built on. So the manual ships asMANUAL.mdand aSessionStarthook tells the model to read it in full (at startup, resume, clear, and after compaction; the hook prints a directive rather than the manual because Claude Code keeps only the first ~2 KB of hook output in context — subagents don't see session context, so the agents read${CLAUDE_PLUGIN_ROOT}/MANUAL.mdthemselves), and the permission profiles ship as data underprofiles/that the human-only/cas:setupinstalls into the repo — showing the diff first, and never choosing a policy in a headless run. The workflows stay single-filecommands/*.mdfor readability; they could migrate toskills/<name>/SKILL.mdfor supporting files orcontext: forkexecution, and would still be/cas:<name>. - Vendored design skill —
/cas:prototypecloses its generative UI gap with Anthropic'sfrontend-designskill, vendored inside the plugin atskills/frontend-design/and loaded ascas:frontend-design(pure markdown — every user and headless run gets it with the plugin, no separate install). It fires only for web UI milestones;cas:ux-reviewercritiques against the same principles, completing the maker/critic pairing for design. - Future hardening — if you ever want a non-bypassable gate (e.g. for unattended fleets), add a
Stophook that refuses to end a turn until/cas:reviewhas passed. Intentionally omitted here to keep enforcement agent-based.
Released under the MIT License — © 2026 Kacper Grabowski. Free to use, fork, and adapt.
Exception: skills/frontend-design/ is vendored from anthropics/skills, © Anthropic, under the Apache License 2.0 (see the LICENSE.txt in that folder; modifications are marked in its SKILL.md). The notice ships inside the plugin with the folder.