How to Build Your Own Developer on Agentic-Nets, With Claude Code Doing the Building

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.

Two ways to run it: the coder needs a host with the toolsDESKTOP LITE (one laptop)the runtime, nativenode, master, gateway, executor, MCP server, Studio on :4200the same host runs the coderclaude, java 21+, maven, git; scanners optionalDocker, for the persona’s own usethe git host container, Testcontainers, verification containersnothing to wire: the native executor already sees your toolsDOCKER COMPOSE (shared runtime)the runtime, in containersnode, master, gateway :8083, executors, Studio, vault, blobstoreone more executor, on a host with the toolspolls the gateway with the executor client, egress onlyDocker on that host, for the persona’s own usethe git host container, Testcontainers, verification containersthe coder lanes name that executor: action.executorId

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.

ToolWho uses itDesktop LiteDocker Compose
Agentic-Nets runtimeeverythingthe appthe compose stack
Claude Code (or another MCP client)you, to build the personayour terminalyour terminal
A headless coding agent (Claude Code, Codex)the coder lanesame laptopthe host executor’s machine
JDK 21+, Maven, gitbootstrap, build, verify lanessame laptopthe host executor’s machine
Dockergit host, Testcontainers, verificationDocker Desktopthe host executor’s machine
trivy, semgrep, gitleaksthe security net (optional, next stage)optionaloptional

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.

The build ladder: a prompt, then a proof, six timeseach step ends with a token you look at on the live runtime before you type the next prompt1 designmeasure the host firstproof:a design documentwith decisions2 setup + auditgit host, bootstrap, auditproof:a scorecardwith evidence3 the looppropose, code, verifyproof:one mergedpull request4 coder as configdefinitions place, pickerproof:a run that namesits agent5 a real goaliterate, send back, mergeproof:a red build sent back,then green6 the brainobserve, curate, applyproof:facts, a plan,a questionStages 1 to 4 fit in one working day on one laptop; stages 5 and 6 took the next morning.

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:

A capability pack: one directory, one artifact, one installcapabilities/hermann/capability.yamlnets/*.net.jsoncompact sources: reads, writes, kindassets/hermann-*.pyone file each, shared lib inlinedseeds/p-*.jsonconfig, goal, the twelve cards, codersapp/agenticos.app.jsonapp/ui/main.mjsstores, actions, one web component5 nets, 38 lanes, 11 scripts, 16 seedsbuildpnml + inscriptionspackagescripts as blobsone artifactkind: capability, signedpublish, installNetHub, then any modelTHE DEV LOOP, EVERY CHANGEpython3 tools/inline-shared.py hermann hermannlibnode tools/pack.mjs build –dir hermannnode tools/pack.mjs package –dir hermann && node tools/pack.mjs publish –dir hermannPOST /api/hub/install {name, version, targetModelId} (or the MCP tool hub_install)Publishing the same version again is a reinstall: seeds stay, scripts and inscriptions update, tokens are untouched.

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.

Studio's Applications page with the Hermann card listing its stores and actions
What a successful install looks like: the application card names every store (a place) and every action (a token it can write). If a store you expect is missing, the pack did not declare its place, and the coder will not find it either.
The Quality tab with the twelve-factor scorecard and per-factor evidence
The proof of stage 2: a scorecard whose every row carries the evidence its lane used. Ask for this explicitly. A score without evidence is a number a model could have made up.

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:

SymptomCauseTell 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 callset oneShot: true on judgement lanes; a JSON reply is then the answer
A script crashes with “str has no attribute get” on a token fieldnested lists and objects come back from the runtime as JSON textdecode 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 emptyrequire only what cannot be empty; ask for the rest in the prompt
A script fails with HTTP 500 writing a tokentoken names are unique per place; two lanes wrote the same nameretry 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 nothingscalars survive that interpolation, arrays do notarchive the whole token and pass only its id
A lane consumes a token and the app can no longer show itthe net consumed the answer or the approvalderive 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).

The Next iteration tab with a proposal of four options
The first human decision of the loop. When the goal is still a placeholder the same lane asks for the goal instead and offers three example goal statements; that is the “goal” mode, and it is the first thing you will see.
The Work tab with two merged runs, their build, coder cost, verification and review
Two merged runs. Every line on a card was written by a script or a contracted lane; the coder’s own summary is collapsed underneath, because it is the one text on the card a model authored.
The Gitea pull request list of the service Hermann builds, two merged pull requests
The git host Hermann provisioned for himself, seen from the outside. Both pull requests were opened by the pipeline, reviewed by a lane and merged by a person. The token that lets the lanes talk to it lives in the vault, never in a token.

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.

The Setup tab with the coding agent picker showing Claude Code and its command template
The coder is a token. Whoever installs the pack edits the definitions; whoever operates it picks here. Adding a third agent is a token write, not a release.

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.

IterationCoderResultCost
sample service, create and read ordersClaude Code, default model, 556 s, 62 turns13 files, 6 tests, merged$1.70
subscription resource with secure webhook channelClaude Opus 5, 815 s, 48 turns28 files, 18 tests, merged$4.73
signed webhook dispatcher, attempt 1Claude Opus 5, 1459 s, 59 turns61 tests, 3 failing, sent back$7.70
signed webhook dispatcher, attempt 2Claude Opus 5, 584 s, 41 turns62 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 brain: reality is measured, the model of it is curated and boundedmerged runobservescript: signals, mapsignals + mapcurateone shot, or headlesscurationapplyscript, size budgetthe brainfacts, plan, asksyou: answers, accepted decisionsWHAT EVERY BRIEF READS FROM ITthe proposal: the plan and the factsthe spec: the facts and the component mapthe coder: the facts, the map, the notes of earlier runsthe curator: everything, to retire what is now wrong

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”.

The Brain tab with the plan and the curated facts grouped by kind
The Brain tab after its first curation. Every fact carries its kind, scope, source and confidence, so a wrong fact can be traced to the run that produced it and retired by the next curation.

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.

The anatomy of a prompt that builds something you can trustWHOa named personaone domainone service at a time“a twelve-factorSpring Boot specialist”WHATthe outcome as anobservable artefactnamed nets and lanes“one lane per factor,a scorecard with evidence”RULESscripts measuremodels judge, contractsthe coder writes, insidean approved spec“one capability pack”PROOFwhat to show, live,with its numbers“measure, never infer”“run one full iterationand show me each step”BOUNDScommit, never pushno secret in a tokenstop and wait afterthe design“then stop and wait”Leave out PROOF and you get a confident summary. Leave out RULES and you get a model that counts its own tests.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *