This is the recipe behind Hermann, the twelve-factor Spring Boot developer who lives in a net: what to install, how to connect Claude Code to the runtime, and the six prompts, in order, that produced a persona which provisions its own git host, bootstraps a service, measures the twelve factors, proposes iterations, writes specs, hires a headless coder, verifies, reviews, merges, and curates what it learns. Every stage ends with something you can check on the live runtime before you give the next prompt. That checking is the method.
What you need, and where the coder has to live
One fact decides your setup. The persona’s coder lane is a command transition: the runtime hands a command token to an executor, and the executor runs a headless coding agent inside the repository. So the headless agent, a JDK, Maven and Docker have to exist on the machine where that executor runs. Everything else can be anywhere.
What I had on the laptop that built and ran Hermann, measured on the day: Claude Code 2.1.259, Docker Desktop 29.7, OpenJDK 23 (the services are built for 21), Maven 3.9.11, git, and the scanners trivy, semgrep and gitleaks from Homebrew. The runtime was Desktop Lite, so the executor was native and saw all of it without any wiring.
| Tool | Who uses it | Desktop Lite | Docker Compose |
|---|---|---|---|
| Agentic-Nets runtime | everything | the app | the compose stack |
| Claude Code (or another MCP client) | you, to build the persona | your terminal | your terminal |
| A headless coding agent (Claude Code, Codex) | the coder lane | same laptop | the host executor’s machine |
| JDK 21+, Maven, git | bootstrap, build, verify lanes | same laptop | the host executor’s machine |
| Docker | git host, Testcontainers, verification | Docker Desktop | the host executor’s machine |
| trivy, semgrep, gitleaks | the security net (optional, next stage) | optional | optional |
Step 0: install, connect, check
Desktop Lite
Download the package for your platform from the latest release, open it, and wait for the tray icon. Studio is at http://localhost:4200. In the tray menu choose Connect Claude Code (copy command) and paste the command into a terminal; it registers the built-in MCP server (an HTTP server on port 8091 with a per-install bearer token) with Claude Code. That is the whole connection.
Docker Compose
git clone https://github.com/alexejsailer/agentic-nets.git
cd agentic-nets/deployment
cp .env.template .env
docker compose -f docker-compose.hub-only.no-monitoring.yml up -d
cat data/gateway/jwt/admin-secret # Studio login at http://localhost:4200
# connect Claude Code to the runtime (stdio MCP server, allowlisted to one model)
claude mcp add agenticnets \
-e AGENTICOS_GATEWAY_URL=http://localhost:8083 \
-e AGENTICOS_ADMIN_SECRET=$(cat data/gateway/jwt/admin-secret) \
-e AGENTICOS_MODELS=hermann \
-e AGENTICOS_ALLOW_MODEL_CREATE=true \
-- npx @agenticnets/mcp
# one more executor on the machine that has Claude Code, Java, Maven and Docker
EXECUTOR_ID=coder-host EXECUTOR_MODELS='*' \
EXECUTOR_UPSTREAM_URL=http://<gateway-host>:8083 \
EXECUTOR_AUTH_CLIENT_ID=agenticos-executor \
EXECUTOR_AUTH_CLIENT_SECRET=$(cat data/gateway/jwt/executor-secret) \
java -jar agentic-net-executor.jar
The host executor polls the gateway with the executor client credentials, so it works from anywhere that can reach port 8083, and it never accepts an inbound connection. When you later tell Claude Code to build the coder lane, add one sentence: “the command lanes that build, verify and code run on executor coder-host“. It will set action.executorId on them.
The check, before any building
Open a fresh Claude Code session in an empty folder and ask it to run the readiness tool and to read the knowledge index. It should report the gateway, the node, the model, the LLM provider and the executor coverage in one answer, and it should be able to list the docs. If either fails, stop here. Everything below assumes Claude Code can read and write the runtime through the MCP server, and can run shell commands on your machine.
Run readiness for the model, then read agenticnets://docs/index and
agenticnets://limits. Tell me what is ready, what is not, and which executor
would run a command lane.
The method: six stages, each proven live
Claude Code is a very capable builder and an unreliable narrator of its own work. Left alone, it will write forty lanes, declare success, and you will find out on the first fire that half the emit rules never matched. The way through is to make it build in stages and to make each stage end with something measured on the live runtime, not described. Six stages worked for Hermann. Each one ends with a proof you look at before typing the next prompt.
Three rules go into every build prompt, in these words or yours. They are not style; they are what makes the result auditable.
- Scripts measure, bounded model calls judge, the coder writes. Every number comes from a deterministic script that writes a token. Every judgement is a one-shot model call with an answer contract, routed to an error place when the contract is missed. The headless coding agent works inside an approved spec, in one repository, with a least-privilege tool list, and never commits or pushes.
- Build it as one capability pack. Nets, scripts, seeds and the application in one directory, packaged into one artifact, installed with one call. Then the dev loop is package, publish, install, and the persona can be installed into any model, including someone else’s.
- Prove every stage on the live runtime. Measure, never infer. Commit, never push. The first sentence forces a demonstration, the second forbids “should work”, the third keeps you in control of what leaves the machine.
Stage 1: the design prompt
The prompts below are the ones I gave, tightened to their essential form. The real session had follow-ups after each, most of them “measure that” or “that is not what I said”, and you will have the same. Give the first one in a fresh session with the MCP server connected.
Measure this machine first: which of claude, codex, docker, java, mvn, git,
trivy, semgrep and gitleaks exist and their versions, and the current Spring
Boot GA line from api.spring.io. Then design a developer persona named Hermann
for Agentic-Nets: a twelve-factor Spring Boot specialist. Research the twelve
factors at 12factor.net and turn each factor into a knowledge card, a
deterministic check lane that scores a repository 0 to 3 with evidence, and a
fix recipe. He needs a net per concern: setup and infrastructure, the
twelve-factor audit, the iteration judgement, the iteration build. He
provisions his own git host on the Docker host. On top he needs a Studio
application where I set the goal and the architecture principles and decide
each iteration from a multiple choice, an interview, or a goal definition.
Rules: scripts measure, bounded model calls judge with answer contracts, a
headless coding agent writes code only inside an approved spec. Build it as
one capability pack. Write the design as a document with the decisions I have
to make and your recommended defaults, then stop and wait.
What came back was a design document: a table of the twelve factors with the Spring Boot practice and the check for each, seven nets with their lanes and places named, the six sections of the application, a build order, and five decisions with defaults (one audit net with twelve lanes rather than twelve nets; Claude Code on the host as the coder; Gitea in a container as the git host; Java 21 on the current Boot line; a working directory). The measuring sentence at the top matters: the design cited the versions it had found instead of assuming them. Read it, change what you want, and answer in one line. Mine was “go with the defaults, the name is Hermann with double n”.
Stage 2: the skeleton, the setup net, the audit net
Build stage one: the pack skeleton, the setup net (the config place, an hourly
infrastructure tick, one setup command lane), the audit net (a digest lane,
twelve factor lanes, one scorecard lane), the scripts, and the seeds (config,
a goal placeholder, the twelve factor cards). Create a fresh model and install
the pack into it. Then prove it live: check the infrastructure, provision the
git host, set a sample service name, bootstrap it, and show me the first
scorecard with the evidence line of every factor. Measure, never infer.
Commit, never push.
This stage is where Claude Code learns the platform’s conventions the hard way, and where you save the most time by insisting on the proof. The pack layout it should produce, and the dev loop it should use from here on:
Things to check before stage 3, all visible in Studio under Applications after you pick the model: the application card with its stores and actions; a running Gitea container; a repository on it with main protected; a scorecard with twelve rows, each with an evidence line that names a path or a setting. My first scorecard was 34 of 36, and both weak marks were bugs in the checks, not in the service (a secrets regex matching inside DATABASE_PASSWORD, and postgresql compared against the image name postgres). That is the kind of thing this stage exists to surface.


Stage 3: the iteration loop
Build stage two: the iteration loop as two nets. Judgement: a trigger becomes a
brief rendered by a script (goal, decisions, service state, scorecard,
history); a one-shot lane proposes as a choice, an interview, or a goal
request; my answer becomes a spec brief and a spec with Given/When/Then
criteria, the API, the migration, the environment variables, the tests and an
out-of-scope list. Build: my approval spawns the headless coder on a branch
with the goal, the decisions, the spec and the factor cards as its brief; the
pipeline, not the coder, runs the build, commits, pushes and opens the pull
request; a verify lane proves the pull request in a clean worktree with a
SHA-tagged image and a running container against Postgres, measuring startup,
probes, graceful shutdown and structured stdout; a review lane checks a
bounded diff against the spec; my merge squashes, tags, re-audits and starts
the next iteration. Every judgement lane is a one-shot call with an answer
contract, routed to an error place when it misses. Run one full iteration on
the sample service and show me each step with its numbers.
Expect this stage to take the longest, because the judgement lanes fail in ways that look like model problems and are platform conventions. Here is the list that cost me hours, so that it costs you minutes:
| Symptom | Cause | Tell Claude Code |
|---|---|---|
| A one-shot lane answers JSON, the run says “no DONE answer within maxIterations” | the agent lane was not in one-shot mode; the loop expected a tool call | set oneShot: true on judgement lanes; a JSON reply is then the answer |
| A script crashes with “str has no attribute get” on a token field | nested lists and objects come back from the runtime as JSON text | decode nested fields on every read, in one shared helper |
| A good answer lands in the error place, “missing required field” | the contract required an array the model left out because it was empty | require only what cannot be empty; ask for the rest in the prompt |
| A script fails with HTTP 500 writing a token | token names are unique per place; two lanes wrote the same name | retry a named write with a suffix, or name by commit and factor |
| A map lane passes a list into a command’s environment and the script sees nothing | scalars survive that interpolation, arrays do not | archive the whole token and pass only its id |
| A lane consumes a token and the app can no longer show it | the net consumed the answer or the approval | derive the inbox from what survives: receipts, specs, runs |
The proof of stage 3 is one merged pull request that the pipeline opened, verified and reviewed, and a fresh proposal waiting afterwards. Look at three things: the spec (are the acceptance criteria testable?), the run record (did the pipeline count the tests, or did the coder say so?), and the verification evidence (startup seconds, probes, shutdown, structured logs).



Stage 4: the coding agent as configuration, and the application
The coding agent must be configuration, not code. Put the agent definitions
into a seeded place next to the coder lane: one token per headless agent with
its command template (placeholders for model, allowed tools and turns), the
brief on stdin, and the result format. Ship Claude Code and the Codex CLI.
Let me choose the agent and the model in the app, default to Claude Code with
Claude Opus 5, and record which agent and model did each run. Then build the
Studio application with six sections: Setup, Goal and Architecture, Next
iteration, Work, Quality, Journal. Every button writes a token into a place
the nets already read; no separate state.
Two things to check. In Setup, the picker shows the agents the place defines and the resolved command line for the selected one. On the next run, the Work tab names the agent and the model that did it. The second check is the one that matters: it means the history stays honest when you switch vendors later.

Stage 5: a real goal, and the send-back path
Up to here the persona built a throwaway service. Now give it something you want. The goal is a token with four fields, and the quality of everything downstream depends on them: a one-line title, a paragraph that says who uses the service, what it must do and what it must never do, a list of principles, and a list of constraints. Mine, for a notification hub next to the Agentic-Nets gateway:
Set the goal: "Notification hub for Agentic-Nets: deliver what waits for a
human." Description: operators register subscriptions (a model, a place, an
optional ArcQL filter, a poll interval) and a channel (a webhook URL with a
shared secret); a poller reads new tokens through the gateway; deliveries are
signed, retried and idempotent; a REST API manages subscriptions and shows
deliveries. First valuable outcome: one subscription on a place delivers each
new token exactly once to a webhook. Principles: twelve-factor; talk to
Agentic-Nets only through the gateway with a client-credentials token from the
environment; every delivery idempotent; small pull requests with tests; REST
with RFC 9457 problem details. Constraints: Postgres only; Java 21, current
Boot line; no Lombok; package com.sailer.agenticos.notify; HMAC-SHA256
signature header, never a query parameter.
Set the service name to agentic-net-notify, bootstrap it, start the iteration,
and take it through: answer his proposal with the recommended option plus my
notes, approve the spec, watch the coder, the verification and the review,
merge. If a build comes back red, send it back with the failing tests and let
him try again. Tell me what did not work as expected, and fix it.
What happened here, measured. The first real spec (the subscription resource) went through in one attempt: 28 files, 18 tests, 815 seconds of Opus 5, $4.73. The second (the signed webhook dispatcher) came back red on the first attempt: 61 tests, 3 failing, all in the timing-sensitive area the spec itself had listed as a risk. One change request with the three test names sent it back to the same branch. The second attempt took 584 seconds and $4.25, found one root cause behind all three failures (two clocks with zero margin), fixed it by making the clock injectable, and merged after a green verification. The send-back path is the part of the loop you most want to have exercised before you trust it, and you only get to exercise it on a real goal.
| Iteration | Coder | Result | Cost |
|---|---|---|---|
| sample service, create and read orders | Claude Code, default model, 556 s, 62 turns | 13 files, 6 tests, merged | $1.70 |
| subscription resource with secure webhook channel | Claude Opus 5, 815 s, 48 turns | 28 files, 18 tests, merged | $4.73 |
| signed webhook dispatcher, attempt 1 | Claude Opus 5, 1459 s, 59 turns | 61 tests, 3 failing, sent back | $7.70 |
| signed webhook dispatcher, attempt 2 | Claude Opus 5, 584 s, 41 turns | 62 tests green, merged | $4.25 |
Stage 6: the brain
After five stages the persona works but does not learn. The notes a coder writes after a run (which packages moved, which convention it chose, what it left undone) never reach the next run; the decisions it effectively takes are buried in specs; every proposal starts from the goal again. The sixth stage adds a curated model of the project, kept by lanes and read by every brief.
Add a brain net. After every merge, a script observes the run (coder notes,
review, verification, diff, scorecard) and measures a component map of the
merged commit in a throwaway worktree: classes by kind, endpoints, tables,
migrations, tests, environment variables. A curator answers a contract: facts
to add and retire, each with a kind (platform, convention, decision, gap,
risk, question), a scope (project or platform), a source and a confidence; the
plan as the remaining increments in dependency order; decisions to propose;
questions only I can answer. The curator is the one-shot lane by default or a
headless agent chosen in the app, from the same definitions place as the
coder. A script applies the curation deterministically with a size budget,
files proposed decisions for me to accept, files questions in my inbox, and
records my answers as high-confidence facts. Every brief reads the brain: the
proposal gets the plan and the facts, the spec gets the facts and the map, the
coder gets the facts, the map and the notes of earlier runs. The next
iteration starts only after the brain has curated the merge. Add a Brain tab.
The proof of stage 6 is what one merge produces. Mine, measured: a component map (43 classes, 8 endpoints, 3 tables, 3 migrations, 15 test classes, 21 environment variables), twelve facts, a six-step plan in dependency order with the merged step marked, four proposed decisions (three of which I accepted because they were already true in the code), and one question only a person could answer: the gateway’s token query contract. I answered it in the app; it is now a high-confidence fact in every brief. The next proposal, started by the brain, said “these options follow the curated plan in dependency order”.

What a build prompt has to contain
Looking back at the six prompts, they share a shape, and the shape is what made Claude Code a reliable builder rather than an enthusiastic one.
A few phrases did disproportionate work. “Measure this machine first” made the design cite real versions. “Show me every step with its numbers” turned a summary into a table I could check. “Tell me what did not work as expected, and fix it” produced a list of platform conventions I would otherwise have discovered one crash at a time. And “then stop and wait” after the design is what kept a forty-lane build from starting before I had read the plan.
Time and money, as far as I measured them
The persona’s own lanes are cheap and fast: proposals in 15 to 25 seconds, specs in 20 to 40, reviews in 15 to 35, curations in about 30, all on one bounded call each. The coder is the whole cost, and it is real: $18.38 of agent time for the four runs in the table above. Stage 1 to stage 4 fit in one working day on one laptop; stage 5 and stage 6 took the following morning. What I did not measure is the cost of the Claude Code sessions that did the building, because the platform’s meter only sees lanes, not the builder’s terminal. If you want that number, ask Claude Code to report it at the end of each stage.
What is not in this recipe
- The security net (dependency, code and secret scanning with a threat note per spec) and the version-currency net are designed but not built. The scanners are installed; the wiring is your stage 7.
- The Codex definition ships but has not run on my machine, because the binary is not on the executor host. The app shows it as missing, which is the honest state.
- The reviewer is the same model family as the coder. A second vendor is one definition token away; I have not proven it is better.
- Three merged pull requests and one send-back is a demonstration, not a track record. The interesting failures (a wrong spec, a coder that loops, a regression the factor checks miss) have not happened in front of me yet.
Start here
Install the runtime, connect Claude Code, run the readiness check, and give the stage 1 prompt with your own domain in place of Spring Boot. Read the design it writes. Then go one stage at a time, and do not type the next prompt until you have looked at the proof of the last one on the live runtime. The persona you get at the end will be yours in every detail that matters: what it measures, what it judges, what it is allowed to write, and what it asks you before it decides.
The pack this article describes lives in the public repository under capabilities/hermann. Every number in it was measured by the persona’s own pipeline on one laptop and read back out of the runtime.
Related reading: Agentic-Nets: The First Multi-Layer Agent Runtime With Live Applications on Top for the runtime and the application layer, and One Download, No Docker, No API Key for the Desktop Lite path in detail.