ANTIGRAVITY LABJP
Articles/Agents & Manager
Agents & Manager/2026-05-28Advanced

Forensic Audit Trail for Antigravity Background Agent — Cloudflare R2 logging that reconstructs decisions six months later

How to design a decision-log audit trail for long-running Antigravity Background Agents so you can still reconstruct why an agent did what it did six months later — schema, R2 write layer, PII masking, and Polars queries.

antigravity435background-agent8audit-trailforensicscloudflare-r2observability19

Premium Article

About four months into running Antigravity Background Agents in production, a different kind of question started showing up in my head. Not "is the agent working today?", but "what exactly was the agent looking at when it bumped that Remote Config value last month?" — the kind of question you only ask when you actually need to reconstruct context after the fact.

I have been running an independent app business since 2014 as Masaki Hirokawa (the artist behind Dolice). The wallpaper apps have crossed 50 million cumulative downloads, and AdMob revenue optimisation runs through a chain of Antigravity agents. Agent A flips a Remote Config flag, Agent B reads that flag to rebalance ad fill, Agent C writes the next morning's report. If even one link loses its reasoning trail, the monthly report stops making sense.

The artistic side of my work (17 international art prizes) and the indie-developer side share one habit: a respect for the long view. Decision logs are not glamorous infrastructure, but four months in, I believe they are the kind of foundation worth investing in before you wish you had.

Long retention changes what "good logging" means

For short-term debugging, plain text in Cloud Logging is fine. I ran on exactly that for the first few weeks. The system started to creak the moment I tried to revisit a decision from three months earlier.

The text log only said "set Remote Config adSlot_A to 0.65". The reasoning behind 0.65 — which metric window, which feature flags, which prompt, which model version — was gone. By that point the agent itself had no memory of the run either. The only way to bring that context back is to write it down in structured form at decision time.

My three guiding rules ended up being:

  1. Record the inputs, not just the outputs (observed metrics, preconditions, candidate scores).
  2. Pin prompt and model to immutable identifiers (hash, version tag).
  3. Strip PII at write time. Retroactive anonymisation almost never works in practice.

A four-layer schema that stays under 12 KB

The schema I settled on splits each log line into four layers. Each line stays around 12 KB even with reasoning candidates included.

type DecisionLogV2 = {
  // Layer 1: identity (who, when, what)
  ts: string;            // ISO8601 with millisecond precision
  trace_id: string;      // ULID — sortable by time
  agent_id: string;      // "remote-config-tuner@v17"
  parent_trace_id?: string;
 
  // Layer 2: inputs (what the agent saw)
  inputs: {
    metric_window: { from: string; to: string };
    observed: Record<string, number | string>;
    feature_flags: Record<string, boolean>;
  };
 
  // Layer 3: reasoning (how it thought)
  reasoning: {
    prompt_hash: string;        // SHA-256 of the prompt
    model: string;              // "gemini-3-pro-2026-04"
    candidates: Array<{ label: string; score: number; rationale: string }>;
    chosen: string;
  };
 
  // Layer 4: action (what changed)
  action: {
    target: string;             // "remote_config.adSlot_A"
    before: unknown;
    after: unknown;
    rollback_token: string;
  };
};

Burning the version into agent_id ("remote-config-tuner@v17") is the single biggest gift you can give your future self. Three months later you can pull the exact prompt template out of the matching Git tag.

The prompt_hash field stores the SHA-256 of the prompt itself. Storing the full prompt on every request inflates R2 cost fast, so I keep only the hash inline and resolve hash to prompt text through a separate immutable table. That deduplication cut my storage by roughly 28%.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A 12 KB-per-request JSON schema and a Cloudflare Workers write path that batches into R2 every minute through a Durable Object buffer
Four Polars query patterns that let you answer 'why did this agent pick A over B back in January?' from R2-backed NDJSON shards
Twelve regex patterns for masking API keys, device identifiers, and store receipts at write time, so EU GDPR and App Store retention rules are met by construction
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Agents & Manager2026-06-21
Letting a Background Agent Work Overnight Without Regretting It by Morning — Guardrails for Unattended Runs
When you hand overnight refactoring to Antigravity's Background Agent, the morning brings as much anxiety as convenience. From three angles — blast radius, completion criteria, and detecting silent regressions — here are the guardrails that let me run unattended jobs with confidence.
Agents & Manager2026-06-17
Tracing Parallel Agents After the Fact: Observability with Structured Logs and Spans
Running multiple agents in parallel on the Antigravity 2.0 desktop makes it impossible to tell which one is doing what. I share an observability design that drops tangled print debugging for run_ids and spans you can trace afterward, with a solo-operator implementation and numbers.
Agents & Manager2026-06-15
Containing Failure in Antigravity Multi-Agent Systems: Three Boundaries That Stop Cascades
Antigravity multi-agent setups run beautifully in isolation but cascade in production, where one small failure drags the whole orchestration down. These notes organize the fix around three boundaries—layered control, trust separation, and observability with idempotency—down to the TOML and the correlation-ID wrapper.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →