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.yamlrequired 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:
- The Primary Agent authors
implementation_plan.md. - The workflow pauses at the Human Gate waiting for explicit user approval (
"Proceed"). - 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:
- Attempt 1 Failure (
escalation_counter == 1): Dispatches a Tier 1 Diagnostician (usingflashfor rapid triage) to isolate root causes against role schemas (schemas/diagnostician-payload.json). - Attempt 2 Failure (
escalation_counter == 2): Escalate toprofor high-reasoning diagnosis, or dispatch external second-opinion review (WorkBuddy AI). - 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.mdhuman review. - Formatting requirements for
walkthrough.mdturn 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:
| Metric | Before (1.x Strict) | After (2.x Adaptive) | Impact |
|---|---|---|---|
| Simple Config Edit Latency | 45–90s (Plan + Spawn) | < 3s (Direct Execution) | 30x faster for routine edits |
| Subagent Cold Start | 4.2s per task | 0.3s (Warm Reuse) | 14x faster worker turnaround |
| Model Token Costs | Pro-heavy ($$$) | Flash-first ($) | ~75% reduction in token burn |
| Instruction Following at Turn 50+ | ~68% compliance | > 98% compliance | Zero attention amnesia via PreInvocation |
| Command Injection Incidents | Zero | Zero | Complete 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