From One Sentence to Live Deploy in 2:44
I dropped a single sentence into a Petri-net inbox at 15:48:56 UTC. By 15:51:40, a lime-green banner with the exact text I asked for was rendering on a public production site. No human touched a keyboard between those two moments.
This is what Safe-Teams — an AgenticNetOS net that models a full SAFe agile team as five cooperating sub-nets — actually does in production. Not a demo, not a sandbox: a real Angular app, a real git repository, a real container redeploy, a real public URL. The story below is the receipts, including the part where the QA agent rejected the first attempt and the rework loop turned a bug-flag into a polish improvement.
Five timestamps, three LLM tiers, one running container restart, zero human keystrokes.
The Setup: Five Roles, Five Nets, One Bare Repo
Safe-Teams isn’t one big agent that does everything. It’s five small sub-nets, each modelling a single role from a SAFe agile team. The PM is the only one that talks to the user. The rest run silently behind a shared inbox — just like a real team. The Developer’s actual code edits happen inside a workspace volume, and when the work is done the agent pushes to a bare git repo. A post-receive hook then triggers an auto-deploy daemon. Nothing in this chain talks directly to Docker or Kubernetes. The git push is the deploy.
The orange arrows are the most interesting part. There is no Jenkins, no GitHub Actions, no GitOps controller in this loop — just a 12-line shell script glued to git’s post-receive hook, a tiny HTTP daemon that knows how to docker compose up -d, and a public nginx fronted by Apache. The git push is the deploy.
The Tier System: Why the LLM Bill Doesn’t Blow Up
Earlier this week I added per-transition LLM tier selection to AgenticNetOS. Every agent transition can now declare "tier": "low" | "medium" | "high" in its inscription. The provider-specific model env-vars (OLLAMA_HIGH_MODEL, OLLAMA_MEDIUM_MODEL, OLLAMA_LOW_MODEL) wire those tier names to concrete models. In this run:
| Tier | Model | Used by | Why |
|---|---|---|---|
| low | gemini-3-flash-preview:cloud | ops watchers, scrum-blocker-sweep, daily-train-status | Mechanical scans, heartbeat work |
| medium | qwen3.5:cloud | PM intake, Developer, QA, DevOps | Real work, but pattern-driven |
| high | deepseek-v3.1:671b-cloud | Architect, PI planning, knowledge-graph synthesis | Genuine architectural reasoning |
The economic shape this gives you is unusual. For one story, the high-tier model fires once (the Architect, on decomposition). The medium-tier model fires four to six times (PM, Dev, QA, DevOps, plus any rework). The low-tier model handles every scheduled scan that runs all day. The expensive thinking happens only when there’s actual ambiguity to resolve.
The Story, Timestamped
Here is the actual prompt I dropped into p-pm-inbox at 15:48:56 UTC. No formatting tricks, no special structure — it’s just plain English a colleague would write:
curl -X POST "http://master:8082/api/runtime/places/p-pm-inbox/tokens?modelId=safe-teams" \
-d '{
"name":"verify-live",
"data":{
"text":"Add a visible LIVE BADGE at the very top of every page of the
git-analytics dashboard. The badge must be a lime-green bar with bold
black text saying EXACTLY: SAFE-TEAMS LIVE 2026-05-12T15:48Z.
Target service: git-analytics-client. Keep the change minimal."
}
}'
And here is what happened next, straight from the master log file:
The single line of code the Developer agent actually committed:
@@ -8,6 +8,7 @@ import { ThemeService } from './services/theme.service';
imports: [RouterOutlet],
template: `
<div class="wrap" style="display:flex; flex-direction:column; min-height:100vh; min-height:100dvh;">
+ <div style="background:#aaff00; color:#000; font-weight:bold; text-align:center; padding:4px 0; width:100%; flex-shrink:0;">SAFE-TEAMS LIVE 2026-05-12T15:48Z</div>
<div style="flex:1; min-height:0; width:100%; position:relative;">
<router-outlet />
</div>
That’s it. One line, exactly placed, with the correct hex code, semantic markup, and inline styles that don’t conflict with the surrounding flex container. The Developer agent didn’t edit the CSS file (which the Architect had suggested); it edited app.component.ts inline template because that’s where the parent .wrap div lives. Real judgment, made by a medium-tier model with a tight Claude-Code prompt.
The Plot Twist: QA Rejected It
The interesting part of this run isn’t the happy path. It’s what happened after the Developer succeeded but didn’t echo the commit SHA in its stdout. The QA agent looked at the dev’s summary, ran its commit-SHA regex against the text, found nothing usable, and routed the token to p-qa-fail with reason="ambiguous".
This is the safe-teams design at work: never let a deploy through on faith. If you can’t prove a commit happened, you fail closed. The rework loop kicked in and routed a new story back to the Developer with the diagnostic attached. Here’s the part that surprised me:
The rework cycle produced a real engineering improvement. Confronted with a file that already contained the change, the Developer agent inspected the existing markup, identified a layout subtlety (horizontal padding combined with 100% width without box-sizing overflows the parent container), and shipped a one-character-different version that polishes it.
This is not how Stack-Overflow-stitching coding assistants behave. This is what happens when a small, focused model has just enough context (the inscription tells it: read the file, look at QA’s reason, make the smallest change that satisfies QA) and no extraneous responsibility.
Why git push Is The Whole Pipeline
Every CI/CD system I’ve worked with operates on the same shape: trigger → runner → build → artifact → deploy. Adding an LLM agent on top usually means strapping it onto step 1 (the trigger) and praying the rest still works. Safe-Teams inverts this:
- The agent is the trigger. A successful Developer fire ends with
git push origin main. Nothing more. - The hook is the orchestrator. A 12-line shell script on the git server posts to a daemon. That’s the entire glue.
- The daemon is the deployer. Single binary, listens on a port, runs
docker compose up -d. No YAML pipeline file. - QA happens after the fact. The page is already live by the time QA finishes deciding whether to pass or rework. If something is wrong, the next commit fixes it — same path, no rollback needed.
You could argue this is irresponsible. I’d argue it’s honest. The deploy was never going to wait for QA in a system that ships every push to main; pretending otherwise just adds latency. What safe-teams adds is a second-pass quality gate that can rework an already-deployed change in the same flow — and that second pass is good enough to catch real issues, as the rework story above shows.
Real Numbers from This Run
| Metric | Value | Note |
|---|---|---|
| Prompt to live page | 2m 44s | p-pm-inbox at 15:48:56 → banner rendered at 15:51:40 |
| Architect reasoning time | ~8s | deepseek-671b, one CREATE_TOKEN |
| Developer plan time | ~25s | qwen3.5, computes workingDir + Claude-Code prompt |
| Claude-Code edit + commit + push | 13.9s | One file changed, one line added |
| Container rebuild + restart | ~45s | Most layers cached, only Angular re-bundle changed |
| High-tier LLM fires per story | 1 | Architect only |
| Medium-tier LLM fires per story | 4–6 | PM, Dev, QA, DevOps, plus any rework |
| Files changed | 1 | git-analytics-client/src/app/app.component.ts |
| Diff size | +1 line | Original commit. Polish commit was a 1-attribute change. |
Where This Leads
A few uses I’m already chasing:
- Bug-fix-via-Telegram. The PM net is already wired to Telegram. A bug report from a real user becomes a tracked story without any human in the middle.
- Tier-tuning per net. The Architect can stay on deepseek-671b for architecture work and downgrade to qwen for a routine README-fix story — the inscription tells it which tier this particular fire should use.
- Replacing the rework heuristic with crystallized rules. After enough rework cycles teach the system “the dev forgot to echo SHA”, that lesson can be crystallized into a deterministic post-step instead of an LLM round-trip.
- Multi-repo teams. Today there’s one bare repo. Tomorrow each role-net can target a different repo with the same git-push-is-the-deploy pattern.
Try It Yourself
If you have AgenticNetOS running and a safe-teams model deployed, the equivalent injection on your machine is one curl:
# 1. Drop a story into p-pm-inbox
curl -X POST "http://localhost:8082/api/runtime/places/p-pm-inbox/tokens?modelId=safe-teams" \
-H "Content-Type: application/json" \
-d '{"name":"my-story","data":{"text":"Your one-sentence request goes here."}}'
# 2. Watch the master log for tier resolution
tail -F /tmp/agentic-net-master.log | grep -E 'Tier-resolved|deploy complete'
# 3. (Optional) Watch the bare repo
git --git-dir=/path/to/git-analytics.git log --oneline -5
This article was written after the run finished, using the actual log lines and commit SHAs from the run. Every timestamp is real. The screenshot of the rendered banner sits in /tmp/safe-teams-live-banner.png on the machine where I ran it.
Related reading: From Human-in-the-Loop to Living Automation for the pattern-crystallization story, and Executors and Deployment Architecture for the polling-based executor pattern that powers Claude-Code runs inside command transitions.