Atelier · Field Guide · Using the factory on your own repo

Using the Factory

How to point Atelier at any codebase - stamp, wire, scope, and run

Atelier is a software factory with one rule: agents propose, deterministic code disposes. A Python engine runs coding agents inside bounded phases and decides sequencing and acceptance; a web cockpit observes and controls it. The two halves meet at a single SQLite file that is the trace. This guide is the practical path from "I have a repo" to "an agent shipped a change I trust" - the same six moves for any project, the model for scoping a run, which workflow to reach for, and where the guardrails are.

You don't need to read the architecture docs first. You do need a git repo, one model provider key, and a handful of real verify commands. Everything below is language-agnostic; the examples just illustrate the shape.

01 The one rule - and why it makes the factory safe

Get this straight before you scope anything; the rest of the guide just applies it.

Agents propose.

A model runs inside a bounded phase and emits a typed envelope - a plan, a set of edits, a report. It never decides whether its own work is good enough. That call belongs to code.

Code disposes.

A deterministic gate accepts or rejects the envelope - your real typecheck, tests, and lint. A rejected build flows back into the agent to retry. The gate is only as honest as the commands you wire into it.

The trace is the seam.

Every phase, envelope, and gate result is written to one SQLite file (sssf.db) as it happens. The engine writes it; the cockpit reads it live. That file is the single source of truth about a run.

Three coding-agent backends, one abstraction

Each agent runs on claude_code (Claude via the Agent SDK, using your local claude CLI login - no API key), pi (drives other providers via the pi CLI), or cursor (Cursor's models via the cursor-agent CLI login - cursor/* ids, no API key; cost shows as $0 under subscription billing). You set the backend and model per agent in the roster. Anthropic models always route through the SDK automatically. Mix freely - a Claude planner with a non-Claude builder is normal.

Runs are isolated by default when you want them to be

A write-capable run can execute in a sandbox: a persistent git worktree on its own branch, with the land step wired to open a PR. Nothing lands on your working branch behind your back. Isolation is opt-in per launch - see §05.

The engine is trustworthy exactly as far as your gates are real and your write boundaries are tight. Those two things (§02 step 2 and §03) are most of what onboarding is.

02 Onboarding any repo - the same six moves

Atelier installs into a target repo: it stamps a self-contained adws/ tree plus the operator skill, and thereafter operates on the git root of that repo. There's no "target" flag - you run the workflows from the repo root. Onboarding is the same recipe every time:

  1. Stamp the factory. From your Atelier checkout, run uv run engine/adws/install.py /path/to/your-repo (add --init to git-init an empty one). This lands adws/, a starter sssf.config.yaml, prompt templates, a justfile, and .claude/skills/atelier/, and records a manifest so later update.py runs can pull engine improvements without touching your layer. Commit the stamp as its own reviewable change.
  2. Wire the quality gate to your repo's real commands - the single most important step. The quality: block in sssf.config.yaml is just data: a named list of argv. Replace the starters with the checks you actually trust (see below). This is what turns the gate from theatre into a real acceptance bar.
  3. Author the roster. In sssf.config.yaml, set each agent's coding_agent + model, and - critically - a writes: allowlist scoping every write-capable agent to the part of the tree it should touch. The enforcer rolls back anything written outside it.
  4. Fence the load-bearing files. protected_files already blocks the factory's own machinery; add your migrations, auth, secrets, and any file whose breakage is catastrophic. No agent can touch a protected path unless it's named explicitly.
  5. Set keys and smoke-test. Add the provider key(s) your models need to the engine env (a claude_code agent needs none - it uses your CLI login). Then kick a couple of cheap read-only runs and open the cockpit to confirm it sees the db.
  6. Start read-only. Your first real runs are scout and plan - no writes, no commits. Read the envelopes and gate evidence in the cockpit before you ever let a builder touch a file.

Wiring the quality gate - argv, never a shell string

# sssf.config.yaml - each entry is a named deterministic check.
# Rules: argv is a LIST; call binaries by bare name; runs with cwd = repo root.
# The `test` block is what the test phase runs alone; the rest run in a quality phase.
quality:
  typecheck: { argv: ["your typechecker"] }      # e.g. tsc, mypy, phpstan
  lint:      { argv: ["your linter"] }            # e.g. eslint, ruff, cs-fixer
  test:      { argv: ["your test runner"] }       # e.g. pytest, vitest, go test

Why a well-fenced repo is the easy case

"Code disposes" only works if the repo has deterministic checks. Any repo that already ships a real typecheck, a test suite, and a linter - and enforces them in CI or a pre-commit hook - is handing Atelier its acceptance criteria for free. You're not inventing gates; you're pointing quality: at ones that already exist. If a check is missing, the gate can't catch that class of error - so an early, high-value ADW is often adding the tests the gate will then depend on.

03 Scoping a run - one bounded unit of work

The natural unit is one cohesive slice an agent can hold in its head: a module, a package, a feature folder - small enough to reason about, self-contained enough that the write boundary and the test filter line up cleanly. Scope every run with the same four levers.

LeverWhat it does
Scope writes:List the paths the agent may change (e.g. src/billing/ + its tests). The enforcer reverts any file written outside the allowlist - the agent physically cannot stray.
Scope the test gatePoint the test argv at the slice's suite (a --filter/path arg) so the gate runs fast and per-attempt, not the whole suite each retry.
Protect the untouchablesAdd migrations, auth, money paths, secrets, and generated files to protected_files so no run edits them without you naming them explicitly.
Let deterministic checks be the reviewerStatic analysis, type checks, and architecture-boundary tests catch whole classes of bug more cheaply and strictly than an LLM reviewer. Lean on them; reserve the agent reviewer for intent, not correctness.

A tight writes: plus a scoped test gate is the difference between "an agent edited my repo" and "an agent proposed a bounded change that a real check accepted." Keep both narrow; widen only when a run has earned it.

04 Choosing a workflow - task → ADW

An ADW ("AI Developer Workflow") is a script that composes phases. The stamped engine ships a graded set, from read-only recon up to a full lifecycle. Start at the top and earn your way down - each row adds capability and blast radius.

You want to…ADWWrites?Notes
Understand an area before touching itadw_scoutNoRead-only recon. The safe first contact with any module.
Turn a request into a planadw_planplan onlyReview the plan envelope in the cockpit before building. Zero risk.
Run one free-form agent phaseadw_promptper rosterThe smallest ADW: one agent, one prompt, fully traced. Good for probes.
Run lint/typecheck/build onlyadw_quality-No agent; runs your deterministic bundle. Safe, high signal.
Build from an existing planadw_buildscopedImplementation only. Pairs with a plan you already reviewed.
Build with a verify gateadw_build_testscopedImplement, then run the test gate; failures flow back into the builder to retry.
Build with an agent reviewadw_build_reviewscopedImplement, then confirm it matches intent.
Small feature, plan → buildadw_plan_buildscopedTwo-agent chain: planner → envelope → builder.
Feature end-to-end with a gateadw_plan_build_testscopedplan → build → test. The full starter chain.
…plus deterministic qualityadw_plan_build_test_qualityscopedAdds the quality bundle after the test gate.
Full lifecycle with review + docsadw_simple_sdlcscopedplan → build → test → review → document, committing as it goes. Save for once you trust the gates.
Document a change from the diffadw_documentdocs onlyReads git diff, writes docs. Handy after a merge.

Chain ADWs by reusing the --adw-id: run adw_plan, read it, then resume the same session with the planner's context intact for the build. The cockpit can also launch and cancel runs for you - a UI-launched run is byte-for-byte identical to one you'd type at the CLI.

05 Isolation - sandboxes instead of committing to your branch

By default a run executes at the repo root and commits to whatever branch you're on. For anything write-capable on a repo that matters, run it in a sandbox instead: an isolated, persistent git worktree on a named branch that hosts one or more runs. The run's trace still lands in the shared sssf.db, so you observe it exactly the same way - but its file changes are quarantined on their own branch.

What a sandbox gives you

  • A worktree on its own branch - nothing touches your working tree
  • Provisioned once at create (deps, ports, env), so follow-up runs start warm
  • A land hook you configure - e.g. push the branch and open a PR
  • Optional backing services brought up per sandbox (DB, compose stack) and torn down on shutdown

How you drive it

  • Configure the sandbox: block once in sssf.config.yaml
  • Create a sandbox and bind runs to it; the worker provisions it
  • When you're happy, trigger Land - the hook runs once in the worktree (PR / merge / manual)
  • Shut it down when done; the branch survives teardown

The control plane never spawns a process

This is the determinism spine, and it's why UI control is safe: the cockpit only writes an intent - enqueue a launch spec, flip a cancel/land/shutdown flag. A single worker turns those intents into real runs and disposes them. The UI cannot mutate a run's trace or its acceptance. Keep that invariant if you extend either side.

06 Guardrails & common gotchas

GotchaSevWhat to do
A default run commits to your current branchHIGHRun anything write-capable in a sandbox (§05) so changes land on their own branch, or switch to a throwaway branch first. Never run a build/commit chain directly on your main/release branch.
An empty or fake quality gate reports false greenHIGHWire real argv before trusting any *_test or *_quality ADW. An absent quality: block runs nothing and says so - don't mistake that for a pass.
Migrations, auth, secrets, money pathsHIGHKeep them in protected_files. These are the paths where a plausible-looking wrong change is most expensive - make agents name them explicitly to touch them, which they won't by default.
Shared/symlinked config across worktreesMEDIf your repo symlinks .env, agent-guidance files, or .claude/ into shared state, an agent "editing a config file" can affect siblings. Add those targets to protected_files.
CI that doesn't run the full suiteMEDIf CI skips tests, your quality: gate is the only automated test signal. Treat a passing gate as the bar, and still open a PR for human review.
Wrong model / missing provider keyLOWValidation checks model spelling, not credentials - a missing key fails mid-chain. Point the roster at one shared model until you need per-phase models, so you only manage one key. A claude_code agent needs none.
Repo guidance leaks into agentsLOWAgents see your repo's AGENTS.md/CLAUDE.md as project guidance. Keep operator-only instructions out of those files - put them where only you read them.

07 Suggested rollout - crawl, walk, run

Sequence it so trust is earned by evidence in the cockpit, not asserted. If you have more than one repo, start on the smaller, lower-stakes one.

CrawlObserve - read-only, zero commitsconfirm the trace is faithful
  • Stamp the engine, wire quality:, point the cockpit at the repo's sssf.db.
  • Run adw_scout + adw_plan across a couple of low-risk areas. Read every envelope and gate report.
  • Goal: prove the trace matches reality and the gates fire - before any write.
WalkFirst writes in a low-risk areasandboxed, test-back-fill
  • Run write-capable ADWs in a sandbox. Start with adw_build_test to back-fill tests on a well-bounded module.
  • Review the resulting branch as a normal PR. Measure gate pass-rate, retries, and token cost per run in the cockpit.
  • Graduate to a small adw_plan_build_test feature once the loop feels boring.
RunTrusted lifecycles, gates hardenedhigh-stakes paths stay human-only
  • Only after the easy cases are routine. Move to adw_simple_sdlc for full plan→build→test→review→docs runs.
  • Keep the scope tight and the untouchables in protected_files indefinitely - money, auth, and migrations stay human-only.
  • By now the deterministic checks do the hard part: a strict typecheck, real tests, and boundary checks catch what a human reviewer would miss, and never get bored doing it. Lean on them.

Everything above is launchable from the CLI or the cockpit and watched in the same live trace. The rollout is about trust, not features - the engine can do the last row on day one; you shouldn't let it until the first two are boring.

Field guide - a companion to the build plan, the long-form engineering docs in the repository, and the operator skill (/atelier). · The three things to get right before your first write: wire the quality gate, scope writes: and protected_files, and run write-capable ADWs in a sandbox. · Start read-only, start small, and let the deterministic gates be the reviewer.