A pattern essay and a milestone. The follow-up to [Personas, Tools, and Teams That Talk to Themselves](https://alexejsailer.com/2026/04/personas-tools-and-teams-that-talk-to-themselves/) — except this time the team doesn’t just talk to itself. It ships code. Real commits, in a real repository, with no human in the loop after the chat message.
For a few months I’ve been writing about Agentic-Nets the way you’d write about a really clever metaphor: the net is the org chart, the tokens are the work, the personas are the team. Nice prose. The kind of sentence that sounds like a breakthrough until you ask “okay, but what does it actually do?”
This week the metaphor stopped being a metaphor.
I wired eight SAFe personas — Product Manager, Architect, Developer, QA, DevOps, Scrum Master, Release Train Engineer, Domain Expert — into a single Petri net inside AgenticNetOS. They share an inbox. They pass tokens. They run on a schedule. And starting this week, they ship code to a real repository, in real time, from a single chat message.
The model is called `safe-teams`. The product they develop is `git-analytics` — a Java/Spring + Angular monorepo that exists in `/Users/alexejsailer/Developer/git-analytics` on my machine. They opened a chat conversation, decomposed a feature request into tasks, ran Claude Code against each task, validated the result, kicked work back when the developer refused the brief, retried, built the artifact, and produced a commit. Concrete commits. SHAs you can `git show`.
This essay is the architecture, the proof, and the next step: soon, anyone will be able to do the same thing on `agentic-nets.com` — drop a feature request in chat, watch a virtual SAFe team build and deploy it. Below is what’s already running, what’s still rough, and the bigger pattern that makes this not just possible but natural.
The eight personas, the topology, and what flows between them
The principle behind Agentic-Nets is uncomfortably simple: the structure of the net IS the architecture of the system. Adding capability means adding places and transitions, not writing code. The SAFe team is a direct expression of that principle — every SAFe role is a persona, every persona is a sub-net inside one model, and the entire team coordinates by writing tokens into each other’s inboxes.
Here’s the topology — eight personas, one model, tokens flowing between them:




Eight personas. Twenty-nine transitions, twenty-seven of them continuously polling. Six sibling sessions inside one model. Persona work crystallises into commits; coordination work crystallises into knowledge tokens. The whole thing stays alive between feature requests — it’s a permanent organism with a heartbeat.
The PM is the only human-facing surface
The model is deliberately funnel-shaped. One inbox, one persona between human and machine: the Product Manager. The user types something — anywhere from “fix the typo on line 42” to “add OAuth2 login” — and that text lands in `p-pm-inbox`. From there a MAP transition stages it (a small but load-bearing detail; without it, the agent re-consumes its own previous reads in a loop and the disk fills up — a class of bug from earlier net designs that we now reflexively guard against), and the PM agent decomposes it into a canonical story token.
The story token has the SAFe shape every senior PM recognises:
{
"storyId": "STORY-2026-001",
"title": "Add a HEALTH.md to git-analytics-core",
"description": "Brief description of what's needed and why.",
"acceptanceCriteria": [
"HEALTH.md exists at the repo root",
"File describes how to verify the running app is healthy"
],
"priority": "low",
"type": "docs",
"targetService": "git-analytics-core",
"targetRepo": "git-analytics",
"status": "new",
"_correlationId": "STORY-2026-001"
}
This token is what flows downstream. Every persona that touches it appends a `history[]` entry — `{persona: “architect”, action: “decomposed”, at: “…”}`. By the time the story reaches DevOps, you can read its full life from a single token. Provenance is built into the data structure, not bolted on.
PM’s only job is to produce ONE story per user message. Anti-hallucination rules in the agent’s prompt make this load-bearing: NEVER invent file paths (read them from `p-pm-config`), NEVER produce more than one story per call, NEVER add fields the schema doesn’t have. The result is that PM is small, fast, and reliable — the bottleneck is wide.
The Architect breaks stories into developer tasks
This is the part of SAFe that traditional agile coaching glosses over: how does a feature get split into tasks? In a real team, that’s the architect’s job. Read the story, decide what files need touching, decide whether it’s one cohesive change or three separate pieces of work, hand each one off as a task with concrete file targets and design notes.
The Architect persona does exactly that — and goes one structural step further than the original design doc proposed. Instead of just enriching a story with notes, it emits 1..N task tokens, hard-capped at five per story, each with its own `storyId` (suffixed `-T1`, `-T2`, …) and `parentStoryId` for lineage:
storyId STORY-2026-001-T1
parentStoryId STORY-2026-001
title Create HEALTH.md at git-analytics-core root
description Add a one-page health-check doc with the actuator URLs
fileTargets HEALTH.md
designNotes Single-file documentation; no code changes
status ready-for-dev
The Architect agent reads three tokens before it decides: the story, the architect’s own config (max-tasks-per-story, code-style preferences), and the project config (workspaceRoot). It composes; it does not invent. If you ask it for a five-line typo fix, it emits one task. If you ask it to add a new endpoint with input validation and a test, it emits three. The decomposition logic is pure prompt — there’s no LangChain, no orchestration framework, no router. The transition is a normal AgenticOS agent transition, and the prompt is the algorithm.
There’s one more thing the Architect does, and this one I’m particularly happy with. As of this week, before writing any task token, it queries the team’s accumulated knowledge place for prior decisions on similar topics. The Scrum Master writes weekly retro tokens into `p-team-knowledge` (“we tried X, it failed because Y”); the Architect now reads them at decomposition time and cites them in `designNotes` with a literal `Prior decision: …` prefix. The team has a memory. The Architect has the discipline to consult it.
The Developer is Claude Code in a heredoc
The Developer persona is the part that surprised me most when it worked. The whole AgenticOS premise has always been “agents call tools” — but for a coding agent, the right tool is another coding agent. Specifically, Claude Code, run as a subprocess, with a focused per-task prompt.
Here’s the kernel of the entire pattern, lifted verbatim from the deployed CommandToken template:
"command": "claude -p \"$(cat <<'PROMPT_EOF'
${input.data.userPrompt}
PROMPT_EOF
)\" ${input.data.claudeFlags} < /dev/null 2>/dev/null",
"workingDir": "${input.data.workingDir}",
"timeoutMs": "${input.data.timeoutMs}"
That’s it. A Petri-net MAP transition wraps a natural-language prompt in a bash heredoc, injects it into Claude Code via `-p`, redirects stdin to `/dev/null` (without that one detail the executor hangs forever — the smallest correct line in the system), and fires the command transition pointed at the right working directory. The Claude Code process runs inside `git-analytics-core/` (or `-client/` or `-docker/`, depending on the task’s `targetService`), edits whatever files it needs to edit, runs `git add` on those files, runs `git commit` with a message prefixed by the task’s `storyId`, and exits.
The result token contains the exit code, the stdout, the stderr, and the duration. A downstream MAP normalises it into a canonical `dev-done` token and routes it on. The first feature request I ran end-to-end produced a real commit (`6e245e8`, “Add HEALTH.md documentation”) in twenty-five seconds of wall-clock time, no manual fire, no babysit, no human in the loop after the chat message.
The “muscle” of the team is just `claude -p` + a working directory + a heredoc.
QA refused-as-success: when honesty is a feature
Here’s the part that matters most to me, and it took the longest to get right.
The Developer persona will sometimes refuse a task. Claude Code is a senior engineer; if the brief is structurally bad — say, “schedule `mvn test` to run inside the running Spring Boot app every minute” — it will respond “I want to flag concerns with this story before implementing”, explain why, propose alternatives, and exit. With code zero. No commit.
Without QA, that token would have looked like success. `exitCode == 0`, the result-map routes to `p-dev-done`, and the chain proudly reports a feature shipped while not a single line of code has changed. This is the failure mode of every “autonomous coding agent” demo I’ve ever seen — they only show you the wins, because the losses are silent.
The QA persona’s job is to make those losses loud. The agent reads each `p-dev-done` token, scans the developer’s stdout for a real commit SHA (regex `[0-9a-f]{7,40}` near phrases like “committed as”), and only routes to `p-qa-pass` if it finds one. If the SHA is missing, or if the summary contains refusal phrases (“I want to flag concerns”, “I did NOT”, “won’t proceed”), the token goes to `p-qa-fail` with a structured diagnosis.
And here’s the part that turns this from detection into recovery. A separate transition, `t-qa-rework`, consumes everything in `p-qa-fail` and synthesises a rework task back into `p-dev-inbox`. The rework task quotes the diagnosis verbatim, suffixes the story ID with `-RW1`, and asks the Developer to address the QA feedback. Then the dev chain runs again. With Claude Code’s earlier objections in the brief.
This actually shipped real code. When my “schedule mvn test every minute” story was correctly refused by Dev with a five-bullet explanation of why it would self-DoS the host, the rework loop fed those bullets back as the new brief, and Claude Code took option A — created a `.github/workflows/test.yml` running `mvn test` on push and PR. Real commit `2c0706f`. Issue detected, recovered, shipped — autonomously, without retrying the same broken plan. That was the moment I stopped calling this a metaphor.
DevOps builds the artifact
After QA passes a token, DevOps takes over. The transition runs `mvn -DskipTests package` against `git-analytics-core/` or `npm run build` against `git-analytics-client/`, captures the duration and exit code, and writes a `deployed` or `error` token. Smoke results from this week: a Maven build in 3.8 seconds (warm), an Angular build in 4.9 seconds. Both with `exitCode == 0`. Tokens land cleanly in `p-devops-deployed`.
A scheduled health-check fires every hour against the local Docker Compose stack (Mongo + Kafka deps) and the AgenticNetOS master itself, writing a heartbeat token into `p-devops-health`. It’s a rough first pass — a small bug in the template engine ate one of the shell fallback expressions, leaving some fields empty — but the structure is right. Tightening it is a one-line fix during the optimisation pass.
The DevOps persona is intentionally minimal in this iteration. Real production deploys belong on a staging server with proper artifacts, image registries, and a release ticket. What’s running today is the smallest change that proves the persona slot is wired and reachable. The user will refine.
The cross-cutting personas: Scrum Master, RTE, Domain Expert
Token-driven personas (PM, Architect, Dev, QA, DevOps) are the spine. Three more personas hang off them as the cross-cutting nervous system, scheduled rather than triggered:
- The Scrum Master sweeps every staging place once an hour, looks for tokens older than four hours, writes a heartbeat into `p-blockers`, and escalates to the PM if something is genuinely stuck for more than eight hours. It also runs a weekly retrospective every Friday at 17:00, distilling the week’s blockers into 1-3 lessons in `p-team-knowledge`. “No significant bottlenecks this week” is itself a valid lesson token — silence is data.
- The Release Train Engineer posts a daily train-status summary every 24 hours (`backlog=N, dev-done=N, qa-pass=N, deployed=N`) into `p-rte-status` and relays a copy back into `p-pm-inbox` for the PM to surface to the user. Every Monday it does a PI-planning fire — picks 3-5 backlog stories for the week’s scope, writes them as a plan token in `p-rte-pi-plans`. The plan is advisory; the PM still owns the backlog. So far the weekly plan from this week reads `Minimal backlog at planning time — recommend adding stories before next PI`. Honest, terse, useful.
- The Domain Expert is the architect’s lookup. Every architect decomposition starts with a `QUERY_TOKENS` against `p-team-knowledge`, scanning recent retro lessons for relevance to the current story. If a prior decision matches, it gets cited verbatim in the task’s `designNotes`. The Architect doesn’t have to remember; the team does.
The combined effect is that the team has memory, has rhythm, and has a way to surface its own pain. You don’t have to ask “what’s blocked?” — the Scrum Master has already written it down. You don’t have to ask “what shipped this week?” — the RTE already posted the summary. The model is alive between feature requests.
It’s not locked to one model, one CLI, or one chat surface
Two things I want to be very clear about, because they make the difference between “a clever demo built around Claude Code” and “a substrate you can run your team on”.
First, the LLM is a knob, not a constant. The CommandToken pattern wraps `claude -p`, but that’s a choice — not a requirement. You can swap the muscle layer for Claude Opus 4.7 when you need the deepest reasoning, or Sonnet when you need throughput, or Codex when you’ve standardised on OpenAI, or a local Ollama model running on your laptop when you’re offline or privacy-sensitive. Each persona’s agent transition has a per-transition `modelId` field, so a single team can run Opus for the Architect (the one that has to think structurally), a faster model for the Developer (the one running per-task in tight loops), and a small local model for the Scrum Master’s hourly sweeps (read-heavy, low-stakes). The GUI’s workflow builder exposes this as a dropdown — pick your provider per persona, per transition, no code changes. The team is the topology; the brains are configurable.
Second, the chat surface is also a knob. The Universal Assistant is one front-end. The CLI is another (run a feature request as `agenticos chat –model safe-teams “Add OAuth2 login”` from your terminal). And there’s a Telegram bot (`agentic-net-chat`) already wired to the same persona system — drop a message into a Telegram chat, the PM intake fires, the team picks it up, and you get a reply when the work is done. Send corrections mid-flight (“actually, make the endpoint return JSON not XML”) and the message lands in `p-pm-inbox` as a new story or a clarification — you’re not interrupting a stack frame, you’re adding a token. The team doesn’t notice or care which surface you used. Every input is a token; every persona just reads tokens.
Third — and this is the part that turns the whole thing from “a clever architecture” into something I genuinely think is a substrate — the nets adapt over time. Tokens in `p-team-knowledge` accumulate lessons. The Architect reads them. The Scrum Master writes them. After a few weeks of operation, the team has a body of its own lore — what worked, what didn’t, what kinds of stories Claude Code consistently refuses, what kinds it nails. And because every persona is itself an agent in the AgenticOS sense (with `rwxhl` capabilities — read, write, execute, HTTP, log access), nothing prevents a future “Net Optimiser” persona from reading the lessons place and improving the inscriptions themselves. Tighten the QA refusal heuristic. Bump the Architect’s max-iterations when a multi-faceted story keeps timing out. Add a sub-persona when a particular kind of work shows up often enough to deserve specialisation. The team doesn’t just use the net to ship code. It can rewrite the net to ship better.
That last loop — the team improving its own structure — is the same Documentation-Driven Reflexive Execution pattern I wrote about a year ago for individual AI tasks, scaled up to organisational structure. Patterns crystallise. AI reasoning handles novel work; once the team has done it three times the work crystallises into a deterministic transition that runs without LLM cost. The cost curve bends down with use. The team gets smarter, faster, and cheaper at the same time.
That’s the breakthrough I think people will eventually point at: not that we automated a software team, but that we built one that learns its own job.
What’s next: agentic-nets.com
What’s running today on my dev machine is the staging build. The plan for the next two weeks is to deploy `safe-teams` exactly as you see it above to `agentic-nets.com`, our public staging endpoint, so anyone can drop a feature request into the same chat surface.
Concretely, this means:
- The chat interface (the existing AgenticNetOS Universal Assistant, pinned to model `safe-teams`) will accept feature requests typed in plain English.
- Each user message becomes one story in `p-pm-backlog`.
- The team picks it up, decomposes it, develops it, validates it, builds it, and posts the result back to the user.
- The target product can be your own GitHub repository — clone it into the SAFe team’s workspace once, and from then on every chat message becomes an autonomous PR-ready commit.
- Honest fail states bubble back. If Claude Code refuses your brief, you’ll see the refusal — not a fake success. If the test suite fails, the rework loop kicks in. If a story is genuinely stuck, the Scrum Master escalates.
This is going to be the first time, as far as I know, that anyone has shipped a complete software-development team as a single autonomous Petri net, with every SAFe role represented, with structured token lineage end-to-end, and with honest failure recovery built into the topology.
I don’t think this is the end state. I think it’s the floor. Once the eight personas are stable, the next obvious moves are: a PO sub-persona that splits epics into stories before PM sees them, a Security Champion persona that scans diffs before QA approves, a UX Designer persona that writes acceptance criteria for visual changes. Each one is another sub-net. The architecture expects extension.
But that’s later. For now, the eight personas exist, they share an inbox, and they ship code. The team is alive.
If you want to be on the early-access list when `safe-teams` lands on `agentic-nets.com`, drop me a message. I’ll send you the chat URL, a sample feature request, and (if you bring your own repo) a link to where your first auto-shipped commit will land.
The metaphor stopped being a metaphor this week. The next post will be from a feature request that I typed and a commit that the team produced, with the human-in-the-loop button finally turned all the way off.
Code: [github.com/alexejsailer/agentic-nets](https://github.com/alexejsailer/agentic-nets) (open-source services + deployment compose). Inscriptions, deploy scripts, and the design doc for the SAFe team are in the closed-source `core/` repo for now — they’ll move to public as the public chat endpoint goes live. Companion essays: [Personas, Tools, and Teams That Talk to Themselves](https://alexejsailer.com/2026/04/personas-tools-and-teams-that-talk-to-themselves/) and [The Reflexive Advisor Team — When Five Agents Hold a Standup About You](https://alexejsailer.com/2026/04/30/the-reflexive-advisor-team-when-five-agents-hold-a-standup-about-you/).