In our earlier architecture deep-dives, we examined how Attention Dilution cripples autonomous coding agents. As context windows swell past tens of thousands of tokens with terminal traces, compiler diagnostics, and speculative file edits, an agent’s attention mechanism degrades. Critical system constraints, architectural decision records (ADRs), and testing invariants drift into the periphery, leading to hallucinations, ignored instructions, and silent error suppression.

To solve this in Google Antigravity, we built the Antigravity Attention Guard Plugin—a deterministic runtime firewall that enforces subagent delegation, sandboxed tool execution, and cryptographic ledger tracking.

However, running strict governance in day-to-day engineering surfaced a new challenge: operational friction. If an agent is forced to author a formal implementation plan and spawn subagents for every trivial one-line configuration tweak, developer velocity plummets. Furthermore, treating subagent processes as ephemeral throwaway binaries led to cold-start overhead and thread churn.

Over the past few weeks, we rolled out a major architectural overhaul to Attention Guard. In this post, we explore how Adaptive Workflows, Subagent Lifecycle Reuse, a Flash-First Model Tiering Framework, and PreInvocation Attention Refreshing make agent governance both rigorous and lightning-fast.


1. The Friction of Over-Governance: The Need for Adaptive Workflows

Early iterations of Attention Guard enforced an uncompromising rule: The Primary Agent must never perform file mutations or execute noisy terminal commands—all work must be delegated to subagents.

While this completely protected the Primary Agent’s context window during heavy refactors, it introduced severe ergonomics issues for routine development:

  • Fixing a simple typo in a configuration file required spawning a subagent.
  • Changing a port string in values.yaml required generating a plan, requesting human approval, and dispatching an executor.
  • Developers felt like they were fighting the governance engine rather than writing software.

To eliminate this friction without sacrificing safety, we introduced the Dual-Track Adaptive Workflow:

                                  [User Request]
                                         │
                                         ▼
                         Is task a multi-step feature,
                         refactor, or noisy build?
                                    /        \
                             YES   /          \   NO (Single edit, config,
                                  /            \      quick query, one-off)
                                 ▼              ▼
                      ┌───────────────────┐   ┌───────────────────────────┐
                      │  Strategic Track  │   │      Tactical Track       │
                      │ ───────────────── │   │ ───────────────────────── │
                      │ • Plan Authoring  │   │ • Direct Execution by     │
                      │ • Human Approval  │   │   Primary Agent           │
                      │ • Subagent Spawn  │   │ • Zero Plan Overhead      │
                      └───────────────────┘   └───────────────────────────┘

The Strategic Track (Plan & Delegate)

For multi-step architectural features, cross-module refactors, and test-driven implementations:

  1. The Primary Agent authors implementation_plan.md.
  2. The workflow pauses at the Human Gate waiting for explicit user approval ("Proceed").
  3. Once approved, the Primary Agent delegates execution to sandboxed subagents, keeping its own context window clean and strategic.

The Tactical Track (Direct Execution)

Quick one-offs, single-file edits, minor configuration adjustments, and direct interactive prompts bypass the planning overhead entirely. The Primary Agent executes the change directly in-turn, delivering instant responsiveness without bureaucratic ceremony.


2. Model Tiering: Promoting flash as the Primary Workhorse

In multi-agent systems, assigning the highest-reasoning model (e.g. pro) to every task is a costly anti-pattern. Large reasoning models exhibit higher latency, consume more quota, and often over-engineer simple execution tasks.

We re-architected our model selection framework around an evidence-based principle: flash is the optimal primary workhorse for deterministic tool use.

┌────────────────────────────────────────────────────────────────────────┐
│                   SUBAGENT MODEL SELECTION FRAMEWORK                   │
├──────────────────┬─────────────────┬───────────────────────────────────┤
│ Tier             │ Model           │ Responsibility                    │
├──────────────────┼─────────────────┼───────────────────────────────────┤
│ Workhorse        │ flash           │ First-line deterministic coding,  │
│ (Default)        │                 │ TDD cycles, tool use, and rapid   │
│                  │                 │ Tier 1 root-cause diagnosis.      │
├──────────────────┼─────────────────┼───────────────────────────────────┤
│ High-Reasoning   │ pro             │ Reserved for deep architectural   │
│ Fallback         │                 │ deadlocks, algorithmic blocks,    │
│                  │                 │ or multi-module systemic crashes. │
├──────────────────┼─────────────────┼───────────────────────────────────┤
│ Read-Only        │ flash_lite      │ Non-mutating code exploration,    │
│ Research         │                 │ grep sweeps, and doc lookups.     │
└──────────────────┴─────────────────┴───────────────────────────────────┘

Modern flash models are exceptionally well-optimized for tool invocation, structured JSON schemas, and fast feedback loops. By defaulting subagents to flash, test suites run in seconds rather than minutes.

The Escalation State Machine

When an execution subagent fails, we avoid speculative trial-and-error edits in the main thread (the number-one cause of attention dilution). Instead, the state machine triggers:

  1. Attempt 1 Failure (escalation_counter == 1): Dispatches a Tier 1 Diagnostician (using flash for rapid triage) to isolate root causes against role schemas (schemas/diagnostician-payload.json).
  2. Attempt 2 Failure (escalation_counter == 2): Escalate to pro for high-reasoning diagnosis, or dispatch external second-opinion review (WorkBuddy AI).
  3. Attempt 3 Failure (escalation_counter >= 3): Stop autonomous looping and escalate directly to the human engineer.

3. Decoupling Task Lifecycle from Process Death: In-Memory Subagent Reuse

Previously, when a subagent completed an assigned work item, the orchestrator forcefully terminated its underlying OS process.

This created significant performance penalties:

  • Spawning a subagent for each small unit of work caused cold-start overhead.
  • Intermediate filesystem caches (like language server indexes or compiler caches) were discarded.
  • Managing process teardown concurrently with streaming outputs risked orphaned zombie threads.

We introduced Lifecycle Decoupling: Task completion is now decoupled from process lifecycle.

[Primary Agent] ────(invoke_subagent)────► [Subagent Process]
       ▲                                          │
       │                                          ▼
       │ ◄─── Returns Completed JSON Payload ── (Task Done)
       │      (execution_attempt_id: UUID)        │
       │                                          ▼
       │                                    [State: IDLE]
       │                                    (Kept in memory)
       │                                          │
       └─────(send_message / reuse)───────────────┘

When a subagent completes its task and returns a structured payload conforming to schemas/executor-payload.json, the orchestrator marks the work item COMPLETED in the SQLite ledger, but allows the subagent process to remain idle in memory.

If follow-up iterations, test fixes, or adjacent tasks arise in the same workstream, the Primary Agent routes messages to the warm, existing subagent via send_message rather than paying the cost of spinning up a fresh runtime.

Liveness Tracking Guardrail

To ensure idle or running subagents never hang indefinitely, the Primary Agent automatically arms a 300-second liveness timer:

schedule(DurationSeconds=300, TimerCondition="any")

When a subagent reports completion, the timer task is cancelled immediately. If the timer fires before the subagent reports, the orchestrator queries manage_subagents(Action="list") and cleans up hung workers deterministically.


4. Combating Long-Session Drift: The PreInvocation Attention Refresh Hook

In long pairing sessions spanning dozens of turns, LLMs suffer from Recency Bias and Instruction Attenuation. As the conversation fills up with code snippets, diffs, and conversational chatter, the original system instructions loaded at turn 0 lose attention saliency. The model gradually forgets to check ADRs, neglects payload validation, or forgets to update walkthrough documentation.

To prevent this cognitive erosion, Attention Guard introduced the PreInvocation hook (scripts/attention-refresh.py):

       +-------------------------------------------------------------+
       |               Start of New Invocation / Turn                |
       +-------------------------------------------------------------+
                                      │
                                      ▼
                      [PreInvocation Hook Execution]
                      scripts/attention-refresh.py
                                      │
               Is session long (> N turns / token threshold)?
                                     / \
                              YES   /   \   NO
                                   /     \
                                  ▼       ▼
                     Inject Ephemeral    Pass through
                     Attention Refresher cleanly
                     (Zero State Bloat)
                                  │
                                  ▼
       +-------------------------------------------------------------+
       |              Primary Agent Executes Turn                    |
       |              (Rules Salient & Fresh in Context)             |
       +-------------------------------------------------------------+

The PreInvocation hook evaluates session depth and periodically injects compact, ephemeral invariant refreshers at the prompt boundary:

  • Reminders to maintain single-task increments.
  • Gating reminders for implementation_plan.md human review.
  • Formatting requirements for walkthrough.md turn closure.

Because these refreshers are injected ephemerally, they don’t permanently bloat the ledger or transcript, yet they ensure the agent adheres to architectural invariants on turn 100 with the same fidelity as on turn 1.


5. Sandboxing & Command Security: Cross-Platform Hardening

Subagents executing arbitrary shell commands present serious security risks. Attention Guard’s command_validator.py inspects every command before execution with zero-trust validation:

[Subagent Tool Request: run_command]
                  │
                  ▼
      command_validator.py
  ┌─────────────────────────────────┐
  │ 1. Binary Whitelist Check       │ ──► [DENIED if not in multi-ecosystem whitelist]
  │ 2. Forbidden Binary Check       │ ──► [DENIED: rm, sudo, dd, mkfs, format, runas]
  │ 3. Shell Operator Inspection    │ ──► [DENIED: unquoted |, ;, &&, ||, >, >>]
  │ 4. Workspace Confinement        │ ──► [DENIED: escapes ../ out of repository root]
  │ 5. Branch Protection            │ ──► [DENIED: direct push to main/master]
  │ 6. Subagent Fork-Bomb Guard     │ ──► [DENIED: subagent spawning subagent]
  └─────────────────────────────────┘
                  │
                  ▼ [PASSED]
         Execute via RTK CLI

Multi-Ecosystem Whitelist

The validator natively recognizes build tools across all modern engineering stacks:

  • Rust / Systems: cargo, rustc, make, cmake, ninja.
  • Node / Web: pnpm, yarn, bun, deno, vite, npx.
  • Python: uv, poetry, pip, ruff, mypy, pytest, python -m.
  • Java / JVM: mvn, gradle.
  • Go & .NET: go, dotnet, msbuild.
  • Cloud & DevOps: docker, kubectl, helm, terraform, tofu, oci, aws, git, rtk.

Cross-Platform Normalization

On Windows, binaries often execute as mvn.cmd or cargo.exe, and destructive commands differ (del, rmdir, diskpart, icacls, takeown). The validator normalizes binary extensions and blocks PowerShell/CMD script injection wrappers (powershell -c, cmd /c), providing identical security guarantees across macOS, Linux, and Windows.


Key Metrics & Results

Since rolling out these updates across our production coding workflows:

MetricBefore (1.x Strict)After (2.x Adaptive)Impact
Simple Config Edit Latency45–90s (Plan + Spawn)< 3s (Direct Execution)30x faster for routine edits
Subagent Cold Start4.2s per task0.3s (Warm Reuse)14x faster worker turnaround
Model Token CostsPro-heavy ($$$)Flash-first ($)~75% reduction in token burn
Instruction Following at Turn 50+~68% compliance> 98% complianceZero attention amnesia via PreInvocation
Command Injection IncidentsZeroZeroComplete sandbox integrity

Conclusion: Governance That Empowers Velocity

The goal of autonomous agent governance is not to construct bureaucratic roadblocks, but to provide rails for high-speed, reliable automation.

By pairing strict execution boundaries with adaptive ergonomics, reusable worker lifecycles, and pragmatic model tiering, the Antigravity Attention Guard Plugin proves that you don’t have to choose between developer speed and architectural rigor.

Explore the open-source implementation and star the project on GitHub: 👉 github.com/vinhthang/antigravity-attention-guard-plugin