Loading...
Back to Archive

6 min read

Durable State Swarms Cut Token Costs by 46%, And Make Long-Horizon Agents Work

July 9, 2026

A lot of multi-agent setups still look like this:

one parent chat |- researcher agent |- architect agent |- implementer agent `- reviewer agent

That shape breaks when context bloats and subagents inherit stale assumptions.

Also when crashed worker disappears into the transcript and provider quota issue kills the whole run.

Follow-up questions replay tokens against a chat history that should have been state.

Puppetmaster takes a different position:

Agents should share durable state.

And that is the whole idea.

It is a provider-neutral control plane for agent swarms.

It runs agent workers as independent processes, coordinates them with leases, stores their results as typed SQLite artifacts, routes each task to the cheapest sufficient model, and stitches the final answer from structured outputs instead of raw chat logs.

You do not build a new agent from primitives but put a supervisor in front of the agent tools you already use: Cursor, Claude Code, OpenAI/Codex, Hermes, or a direct provider API through the built-in agentic worker.

Let’s have a look at why durable state beats shared transcript.

Article image

The problem Puppetmaster is solving

Agentic software engineering creates an infrastructure problem.

The workflow includes:

  • long repo investigations
  • conflicting hypotheses
  • multiple tool-capable workers
  • provider fallback
  • patch attribution
  • live progress inspection
  • approval gates
  • reusable memory
  • cost controls
  • repeatable routing decisions

Native IDE subagents help with parallel exploration, and tools like Claude Code now support custom subagents, hooks, MCP, skills, and parallel work.

Subagents have independent contexts that preserve the main conversation and can be routed to cheaper models for specific task types.

That is useful but Puppetmaster goes one layer lower and one layer wider.

Instead of asking one host product to manage every child agent inside its own session, Puppetmaster turns the host agent into an operator and moves the real coordination into a local runtime.

The control flow becomes:

Cursor / Claude Code / OpenAI / Codex / Hermes / agentic / shell | v Puppetmaster supervisor -> task-aware model router | v independent worker processes -> SQLite artifacts, events, memory | v live artifact board -> stitched summary -> zero-token follow-up reads

That is closer to Gunicorn, Redis, or a local workflow engine than a group chat and the important word is runtime.

Article image

Puppetmaster treats a swarm run as a job and a job contains tasks.

Tasks are claimed by workers through leases, workers emit artifacts., and artifacts include payload, evidence, confidence, and hash integrity.

Then the stitcher reads artifacts and writes the final summary.

The core objects are:

Job: one swarm run and user goal Task: a role-specific unit of work, optionally dependent on other tasks AgentRun: one attempt by one worker process Artifact: structured worker output with evidence, confidence, payload, and sha256 MemoryRecord: promoted facts that future workers can retrieve

This sounds much more useful in practice.

Editor’s note: To celebrate reaching 10,000 community members on Medium, who relentlessly design, ship, and iterate on agents every day, we’re also making the full repository available for free, which is part of our Agent Foundry program.

Why durable state beats shared transcript

The common parent chat plus subagents model creates hidden coupling.

In a chat swarm, every follow-up re-sends the whole transcript, so turn n processes roughly n turns’ worth of context.

Per turn that’s linear but cumulatively it’s quadratic, O(n²).

Article image

Your tenth follow-up isn’t a little more expensive than your first, the running total is an order of magnitude higher, and it’s invisible because it hides inside the context window.

Durable state turns a follow-up into a bounded read instead of a replay, which is what the article means by zero-token follow-up reads.

Article image

The actual source model makes this explicit.

In puppetmaster/models.py, artifacts are typed records:

Code
python
class ArtifactType(StringEnum):
  FINDING = "finding"
  DECISION = "decision"
  PATCH = "patch"
  VERIFICATION = "verification"
  RISK = "risk"
  MEMORY_SUMMARY = "memory_summary"
  ROUTING = "routing"
  GATE = "gate"
Code
python
@dataclass(frozen=True)
class Artifact:
  job_id: str
  task_id: str
  type: ArtifactType
  created_by: str
  payload: dict[str, Any]
  confidence: float
  evidence: list[str]
  id: str = field(default_factory=lambda: new_id("artifact"))
  created_at: str = field(default_factory=now_iso)
  sha256: Optional[str] = None

  def validate(self) -> None:
      if not 0 <= self.confidence <= 1:
          raise ValueError("artifact confidence must be between 0 and 1")
      if not self.payload:
          raise ValueError("artifact payload must not be empty")
      if not self.evidence:
          raise ValueError(f"{self.type} artifacts require evidence")

A worker result must have evidence and a patch is not just “I changed the code.”

Also routing decision is not hidden inside logs and verification result is first-class state.

So basically do not make the model transcript your system of record, use the transcript for reasoning and use durable state for coordination.

How Puppetmaster fits with MCP, LangGraph, Claude Code and Codex

The agent ecosystem is crowded, so the positioning matters, and Puppetmaster is not trying to replace any of these existing layers.

It is a supervisor over them.

  • If you are building a custom product agent, use LangGraph, CrewAI, OpenAI Agents SDK, or your own framework.
  • If you are coordinating agentic engineering work across the CLIs your team already uses, Puppetmaster is the missing control plane.

Full-edit workflows with Claude Code

For real edits, Puppetmaster can drive Claude Code in non-interactive mode.

The full-edit config is explicit about the risk surface:

Code
json
{
"lease_seconds": 10,
"workers": [
  {
    "role": "claude-implement",
    "instruction": "Use Claude Code to implement the requested change and leave a reviewable diff.",
    "adapter": "claude-code",
    "payload": {
      "prompt": "Implement the requested change, run focused verification, and keep the result easy to review.",
      "cwd": ".",
      "permission_mode": "acceptEdits",
      "allowed_tools": ["Read", "Edit", "MultiEdit", "Write", "Bash"],
      "output_format": "json",
      "timeout_seconds": 900,
      "allow_dirty": false
    }
  }
]
}

The allow_dirty: false default is important.

Article image

If a write-capable agent starts from a dirty working tree, you lose attribution.

Was that diff produced by the agent, by you, or by yesterday’s half-finished refactor?

Puppetmaster refuses dirty trees by default so patch artifacts stay meaningful.

For serious use, run implementation in a dedicated worktree:

Code
bash
git worktree add /tmp/puppetmaster-work -b puppetmaster-work
python -m puppetmaster claude "Implement the approved fix" \
--cwd /tmp/puppetmaster-work \
--permission-mode acceptEdits

Then inspect before merging:

Code
bash
python -m puppetmaster diff
python -m puppetmaster show $(python -m puppetmaster last)
python -m puppetmaster approve <job_id>
# or
python -m puppetmaster reject <job_id> --reason "Needs narrower scope"

Do not skip this gate.

Autonomous coding agents are useful because they can act and they are risky for the same reason.

Model routing: the part managers will care about

Puppetmaster ships a task-aware model router.

The router uses a user-owned registry in ~/.puppetmaster/models.json.

You define model IDs, adapter names, pricing, billing posture, and capability scores.

The routing logic has three pillars:

  1. a user-owned model registry
  2. a transparent classifier that estimates required capability from role, instruction, and payload
  3. policies like balanced, cheap, quality, and escalating

Every routing decision is stored as a ROUTING artifact.

That means you can inspect the selected model, estimated cost, rejected alternatives, and the reason each alternative was rejected.

Dry-run a decision before spending anything:

Code
bash
python -m puppetmaster models init
python -m puppetmaster models list
python -m puppetmaster route "Security audit across every endpoint" --role audit

The docs show the shape of the output:

picked: claude-code/opus-4-8 (adapter=claude-code, model_name=claude-opus-4-8) policy: balanced capability needed: 99 chosen capability: 99 estimated tokens: in=510 out=5000 estimated cost: $0.127550 why: policy=balanced: cheapest model whose capability_score (99) >= needed (99) rejected:

  • cursor/composer-2-5: capability_score 55 < needed 99
  • cursor/gpt-5-5: capability_score 78 < needed 99
  • openai/gpt-5-4-mini: capability_score 70 < needed 99

For an easy task:

Code
bash
python -m puppetmaster route "Format these files" --role verify-runtime

Expected shape:

picked: cursor/composer-2-5 (adapter=cursor, model_name=composer-2.5) capability needed: 20 chosen capability: 55 estimated cost: $0.000000

This is where the economics get interesting.

Most teams do not need the frontier model for every worker.

Exploration, formatting, basic verification, and small summaries can route to cheaper or plan-billed models.

Security audits, cross-file refactors, and ambiguous architecture decisions can route higher.

Article image

The model decision becomes auditable infrastructure.

The live artifact board is the real UX

Puppetmaster workers write artifacts and events as they run.

Cursor can inspect status, logs, live artifacts, partial summaries, and the final stitched summary.

The local dashboard is also zero-dependency:

Code
text
puppetmaster dashboard [<job_id>]

This gives you a live web board over the local state store.

It is a pragmatic local view: task graph, artifacts, costs, fallback events, and alerts.

Where I would be cautious

Puppetmaster is still daily-driver beta software.

The runtime contract is real, tests are automated, SQLite is the default backend, jobs fail closed, and validated full-edit adapters exist.

It is not yet a hosted multi-user production service, and take that literally.

Do not point it at sensitive repos without understanding provider data handling and do not assume the router is always right.