Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The Multi-Agent Fleet: Fresh Handoffs, Context Taxes, and the Observability Loop

How a Two-Week Crucible Turned Monolithic Agent Prompts into an Observable Multi-Agent Assembly Line

Who this is for — engineers and architects orchestrating AI coding agents across multi-repository fleets.

Read this if — your agent sessions are getting slow, bloated, prone to hallucination, or colliding on tickets.
Skip this if — you only run one-shot single-file prompt scripts.

Takeaways

  1. The Context Tax is Real: Bloated monolithic sessions degrade agent attention (“lost-in-the-middle”); lean, ephemeral subagent handoffs (/fresh-sprint) slash token consumption by 70–80%.
  2. Telemetry Over Guesswork: You cannot manage prompt drift without empirical metrics; mining Git history directly for document byte/token evolution (harnez dochistory) provides the feedback loop needed for prompt dieting.
  3. Output Distillation Protects Context: Massive compiler and test output drowns the model; automatic PreToolUse shell shimming (harnez distill) preserves error lines while truncating noise.
  4. Green Unit Tests Can Lie: Multi-agent pipelines require real-environment live validation gates; simulated test fixtures often hide runtime hook races and false workflow assumptions.
  5. Concurrency Demands Atomic Primitives: When multiple agents operate in parallel, manual folk practices (ls | grep) fail immediately; atomic reservation (harnez find issues next --reserve) is essential.

1. The Starting Point: The Monolithic Session Trap

In late August 2026, after months of operating an agentic software fleet across twenty repositories (harnez, uman, voxi, ffext, cati, emojig), we hit an invisible wall: the monolithic session trap.

In the early days of agentic coding, the common instinct was to keep a single chat session alive for as long as possible. The operator would feed task after task into the same conversation, accumulating hundreds of tool calls, compiler outputs, git diffs, and lint runs.

The failure mode wasn’t a sudden crash. It was insidious:

  • The “Lost-in-the-Middle” Attention Cliff: As the context window swelled past 80,000 tokens, the agent began silently ignoring explicit rules in AGENTS.md. It would invent ad-hoc commands, repeat fixed bugs, or replace fifty-line clean patches with fragile single-line edits.
  • The Compounding Token Tax: Every single subsequent turn—even asking a one-word clarification—carried the full weight of the massive session history. A 10-turn simple bug fix cost 200,000+ tokens instead of 15,000.
  • Rule Accumulation & Prompt Bloat: Every time an agent made a mistake, the team added another paragraph to AGENTS.md or docs/lang/. Over four months, instruction files doubled in size without anyone measuring what was actually being consumed.
graph TD
    A[Monolithic Long-Running Session] --> B[Context Window Bloat: 100k+ Tokens]
    B --> C[Attention Degradation: Rules Ignored]
    C --> D[Agent Makes Mistakes]
    D --> E[Human Adds More Rules to AGENTS.md]
    E --> B
    style B fill:#ffebee,stroke:#c62828
    style C fill:#ffebee,stroke:#c62828

2. The Breakthrough: The Lean Fresh-Handoff Sprint

To break the cycle, we redesigned the agent workflow around The Lean Fresh-Handoff Sprint (/fresh-sprint).

Instead of treating the AI assistant as a single eternal pair programmer, the host orchestrator acts as an engineering supervisor:

  1. Scoped Objective: The host defines a razor-sharp, single-ticket objective with clear acceptance criteria and explicit non-goal fences.
  2. Ephemeral Subagent Dispatch: A fresh subagent is launched in a pristine context window containing only the baseline project rules and the target ticket.
  3. Autonomous Execution & Self-Verification: The subagent implements the change, verifies it with repo-native test suites (go test ./..., make check), and reports back.
  4. Immediate Teardown: The subagent is killed immediately upon task completion (manage_subagents kill). Zero zombie processes, zero background memory leaks.
graph LR
    H[Host Orchestrator] -->|1. Dispatch Scoped Task| S1[Fresh Subagent 1\nClean 8k Context]
    S1 -->|2. Autonomous Execution| V1[Test & Verification]
    V1 -->|3. Completion Report| H
    H -->|4. Kill Subagent 1 & Commit| G[Git Commit]
    H -->|5. Dispatch Next Task| S2[Fresh Subagent 2\nClean 8k Context]
    style S1 fill:#e8f5e9,stroke:#2e7d32
    style S2 fill:#e8f5e9,stroke:#2e7d32

Empirical Proof: The Three-Ticket Token Accounting Study

On August 28, 2026, we empirically measured a sequential run across three dependency-ordered tickets (Tickets 078 $\rightarrow$ 079 $\rightarrow$ 080: extracting the rograph layout module, adaptive graph shrinking, and panel boundaries):

MetricMonolithic Session (Modeled)Lean Fresh-Handoff Sprint (Actual)Measured Delta
Total Tokens Consumed$\ge$ 460,000 tokens200,372 tokens-56.4% (-260k tokens)
Tool Invocations108 calls (accumulated)108 calls (fresh contexts)Identical work
Context Window at Task 3~145,000 tokens14,200 tokens-90.2%
Turnaround Time~26 minutes8.0 minutes3.25x faster
Rework / Regressions3–5 hallucinated turns0 rework, 0 escalations100% first-pass pass

3. Dynamic Context Pruning: From Injected Rules to Triggered Skills

Why had system prompts grown so large? On August 31, 2026, we ran a Clean-Session Self-Audit across Claude Code and Antigravity. By launching fresh sessions in an empty directory (claude -p / claude -c -p), we measured every byte injected into the baseline system prompt.

The results were alarming:

  • Standing Policy Repetition: The “Context Discipline” rule was injected four separate times with drifted wording across global, user, and project configurations.
  • Heavy Inactive Domains: Massive domain guides (Website.md, ConciseMode.md, and the 1,500-token Tool Feedback Protocol) were being forced into every single prompt turn, even when the agent was just fixing a 2-line Go typo.

The Solution: Skills-Based On-Demand Ingestion

We stripped static prose from AGENTS.md and migrated domain guides into Triggerable Agent Skills (e.g. ~/.claude/skills/website/SKILL.md):

  • Always-on core: Only core invariant boundaries (e.g., Make conventions, structured patch discipline, issue tracking).
  • On-demand skills: Heavy architectural guidelines are ingested only when the user or task explicitly invokes them (/website, /concise-mode, /story).
  • Result: More than 4,200 static tokens removed from every baseline agent turn across the fleet.

4. Protecting Context: Tool Output Distillation (harnez distill)

Prompt instructions are only half the battle. The other half is tool output bloat.

When an agent runs go test -v ./..., npm test, or git status across a monorepo, the terminal tool output can dump 2,000 to 10,000 lines into the model’s context. A single verbose test failure can consume 20% of the entire context window with irrelevant passed-test noise.

The PreToolUse Shell Interceptor

We introduced harnez distill and harnez exec:

  1. Hook Shimming: Claude Code’s PreToolUse hook intercepts shell execution before the command runs.
  2. Transparent Auto-Piping: Long-running or verbose commands are automatically routed through harnez distill.
  3. Smart Error-Preserving Compression: Distillation strips out verbose passing suites, collapses repetitive tracebacks, and preserves compiler errors and failed line numbers in a dense summary.
  4. Byte-Cap Guardrails: Guarantees that no single tool output exceeds safety bounds, preventing runaway token exhaustion.

5. Measuring the Beast: Git History Doc Telemetry (dochistory)

You cannot manage what you cannot measure. Having established that prompt bloat degrades LLM reasoning, we needed an empirical tool to answer: How large are our managed documents, and how have they grown across Git history?

Enter harnez dochistory: a zero-checkout telemetry engine capable of scanning dozens of documents across hundreds of Git commits in under 45 milliseconds.

5.1 Streaming Git Architecture

Traditional tools (git-of-theseus, hercules) checkout working trees or maintain heavy in-memory DAGs. dochistory uses a streaming C-Git pipeline:

  1. git log --follow --raw --abbrev=40 streams commit metadata, file adds, deletions, and renames.
  2. git cat-file --batch streams raw blob objects directly from Git packfiles without touching the working disk.
  3. Blob SHA-1 Caching: Because Markdown files remain unchanged across many commits, metrics (bytes, lines, words, tokens, headings) are calculated once per unique Blob SHA. Cache hit rates exceed 80%.

5.2 Visualizing Prompt Diet in the Terminal

harnez dochistory renders high-density 8-step Unicode sparklines (▁▂▃▄▅▆▇█) and dynamically filtered ANSI-colored stacked category proportion bars across monthly milestones:

── Multi-Doc Token Evolution & Stacked Category History ────────────
Documents: 15 analyzed | Commits: 66 | Unique Blobs: 108 | Cache Hits: 9 (7.7%) | Latency: 41ms
Aggregate Sparkline: [▁▁▁▁▁▁▁▁▁▁▁▁▁▂▂▂▂▂▂▂▃▃▃▄▅▅▅▅▅▆▇▇█▇▇▇▇▇▇▇]  (84 → 20,218 tokens | Peak: 20,639)

── Category Breakdown Across Milestones ────────────────────────────
Legend: █ lang  █ practices  █ root (AGENTS.md)
MILESTONE             PROPORTION BAR                      TOKENS    DOCS
──────────────────────────────────────────────────────────────────────────
May 2026              [██████████████████████████████]         415       2
Jun 2026              [██████████████████████████████]       3,340       7
Jul 2026              [██████████████████████████████]       5,354       9
Aug 2026              [██████████████████████████████]      19,817      15
Present (01 Sep)      [██████████████████████████████]      20,218      15

The output exposed the reality: in May, total documentation was 415 tokens. By late August, it had grown to 20,639 tokens—a 50x increase. With dochistory, we could identify specific oversized practices (AgenticLoop.md at 5,124 tokens) and prune them systematically.


6. The Real-Environment Verification Gap: When Green Tests Lie

The greatest operational lesson of late August came from the Tool Observability Saga (Issues 115–124).

Over two days, eight sequential subagents implemented an automatic tool-call observability and telemetry pipeline. Every single subagent completed its task:

  • 100% unit test coverage was achieved.
  • go test ./... passed with zero errors.
  • Code reviews approved every single diff block.

And yet, when the user started a real agent session, automatic telemetry capture was 100% dead.

What Went Wrong?

  1. Hook Racing in the Agent Runtime: Claude Code executed multiple PreToolUse hooks concurrently. The last hook to finish overwrote earlier command rewrites without error.
  2. Metacharacter Shell Splicing: Splicing raw commands into wrappers broke when commands contained |, &&, or nested quotes.
  3. Workflow Assumption Mismatch in Test Fixtures: The unit test fixtures had mocked a Git workflow where agents operate on isolated ticket branches (feature/116-telemetry). In reality, the operator works directly on main. The code tried to parse branch ticket metadata that did not exist on main, silently aborting telemetry collection.
graph TD
    A[Subagent Writes Code & Mocks] --> B[Mocked Unit Tests Pass: GREEN]
    B --> C[Review Agent Approves PR]
    C --> D[Merged to Main]
    D --> E[Real-World Session Run]
    E --> F[FAILURE: Runtime Hook Race & Shell Pipe Syntax]
    style F fill:#ffebee,stroke:#c62828

The Invariant: Mandatory Live-Environment Verification

This breakdown led to the creation of the Real-Environment Verification Gate in docs/practices/AgenticLoop.md:

  • Unit tests prove that code satisfies internal logic.
  • They cannot prove that runtime hooks, shell parsers, and external daemon processes cooperate under real human workloads.
  • No infrastructure ticket is closed without a live-run verification in a restarted, real agent session with debug logging enabled (DEBUG=true).

7. Multi-Agent Concurrency: The Atomic Reservation Lesson

As multiple agents and parallel sessions began operating on the same repositories simultaneously, a subtle bug emerged: ticket allocation races.

Every agent had been computing the next issue number by running:

ls issues | grep -oE '^[0-9]+' | sort -n | tail -1

When two agents in parallel sessions (or an agent and a human) attempted to file tickets at the same time, both read number 194, creating colliding files and broken Git history.

The Fix: harnez find issues next --reserve

We replaced the ad-hoc shell pipeline with a first-class CLI command:

  • harnez find issues next: Scans both active issues/*.md and archived issues/archive/*.md to calculate true max + 1.
  • --reserve [title]: Atomically claims the slot using os.OpenFile(..., O_CREATE|O_EXCL), creating a placeholder draft ticket. A concurrent caller immediately receives N+1.

8. Live Observability: The Hardware Load Box Alignment

Agentic coding is CPU, GPU, and RAM intensive, especially when running local tokenizers, LLM sidecars, or compiling Rust and Go binaries.

In harnez usage --watch and --compact, we normalized the Hardware Load Box:

  • Zero-Subprocess Direct Kernel Reads: Replaced heavy CLI forks (nvidia-smi, rocm-smi, top) with direct Linux /proc and /sys kernel telemetry.
  • RAM Geometry Discovery: Replaced generic unpadded strings with hardware-aware labels (ram (2x16G) on workstation, ram (45G) on server node @x600).
  • Timeseries Sparklines for All Resources: Unified CPU, GPU, RAM, and VRAM/GTT to display rolling 10-sample sparklines ([▁▂▄▅█]), providing instant feedback on whether a subagent is active, thrashing, or idle:
  • Paced Startup Splash Screen: Replaced the 3-second blank freeze on startup with an immediate alt-screen EWMA-estimated progress bar.
┌─ ⁷ Load ────────────────────────────────┐
│ cpu (12 cores)   [▂▁▁▁▁▁▁▁▁▁] 4% (60°C) │
│ ram (23G)        [▃] 7.6/23.3G 33%      │
│ gpu (Cezanne)    [▁▁▁▁▁▁▁▁▁▁] 9% (50°C) │
│ gpu vram/gtt     [▁] 2.2/19.6G 11%      │
└─────────────────────────────────────────┘
┌─ [R] Remote Load (@x600 · batch) ───────┐
│ cpu (16 cores)   [▁▁▁▁▁▁▁▁▁▁] 0% (29°C) │
│ ram (45G)        [▄] 20.0/45.1G 44%     │
│ gpu (Phoenix1)   [▁▁▁▁▁▁▁▁▁▁] 0% (27°C) │
│ gpu vram/gtt     [▁] 1.5/23.1G 6%       │
└─────────────────────────────────────────┘

9. Polyglot Release Automation: From Go to WebExtensions

The final piece of the two-week evolution was universal release ergonomics.

harnez release originally targeted Go binaries with GoReleaser. In this session, we generalized it into a universal polyglot release engine:

  1. WebExtension & JSON Native: Auto-detects "version": "x.y.z" in manifest.json and package.json, updating versions while preserving exact indentation.
  2. Monorepo Subproject Tagging: Supports tag_prefix: "linklit-v", allowing multi-extension repositories (ffext) to tag and release individual extensions independently (linklit-v1.0.1 vs lazypins-v1.1.2).
  3. Build Target Fallback: Executes make pack or make dist when no GoReleaser YAML is found.

Releasing any project in the fleet—whether a Go daemon, a Zig utility, or a Firefox extension—is now a single uniform command:

harnez release -d ~/git/ffext/linklit --bump patch

10. The Invariant Laws of the Multi-Agent Fleet

As we look across the last two weeks of intensive agentic pairing, six foundational rules have proven invariant:

  1. Kill Finished Contexts Immediately: If a subagent completes its ticket, terminate it. Start the next task in a clean context to avoid the compounding context tax.
  2. Never Add a Rule Without a Metric: Track documentation token weight over time. If a guideline doesn’t prevent measurable errors, prune it.
  3. Offload Standing Prose to On-Demand Skills: Keep baseline instructions minimal. Inject deep architectural rules only when specifically triggered.
  4. Distill Tool Outputs Before Ingestion: Never let multi-megabyte test or build logs flood the model’s context. Intercept and condense them.
  5. Real-Environment Gates Over Mocked Passes: Unit tests verify code logic; only live execution with debug tracing verifies system integration.
  6. Automate Coordination Through Tools, Not Prose: Do not ask agents to “be careful not to pick the same ticket number”; give them harnez find issues next --reserve.