ANTIGRAVITY LABJP
Articles/App Development
App Development/2026-07-09Advanced

Before an Agent's .proto Edit Silently Breaks Binary Compatibility: Gating Wire Compat with buf breaking

When an agent edits your .proto files, the text can look perfect while wire compatibility quietly breaks. Here is how to stop field-number reuse and unsafe type changes with a working gate built from buf breaking and reserved.

antigravity425protobufgrpc2bufapp-dev48

Premium Article

A week after I asked an agent to "tidy up this unused field," a handful of users on an older build of the app started reporting numbers that arrived slightly wrong. If you define a small API with Protocol Buffers as an indie developer, this is entirely plausible.

Look at the diff and nothing seems wrong in the editor. One field is gone, one field is added. As text, it is a clean cleanup. What broke is not the text but the wire format, the compatibility of the serialized bytes.

Since late June, Antigravity's markdown and diff rendering added syntax highlighting for C++, Python, and Protobuf. Readable proto diffs are a welcome change. But readability is not a compatibility guarantee. Eyeballing a proto diff and deciding "looks fine" means guarding the most fragile part of the system with the vaguest possible method.

This article hands that judgment to a machine instead.

An Agent Fixes .proto Correctly as Text

Large language models are good at editing .proto files in a syntactically correct way. They remove unused fields, normalize naming, rewrite comments. That much is trustworthy.

The catch is that Protocol Buffers compatibility is decided not by source text but by serialized bytes. Each field is identified on the wire by its field number, not its name. So renaming a field preserves compatibility, but changing or reusing a field number makes existing binaries interpret those bytes as something else.

An agent optimizes how the source looks. In that frame, assigning a freed-up number to a new field looks like the "cleaner" change. Yet for clients that have not updated, it is an instruction to read the old field's value as the new field.

I have felt out this boundary firsthand more than once. What I let an agent do is meaning-preserving formatting; anything that changes what a number means must pass a gate, human or machine. Blur that line and your tests pass while production alone breaks.

The Common Ways Wire Compatibility Breaks

Failures tend to collapse into three shapes.

First, field-number reuse. Delete field 3 and later add a differently typed field 3, and the old client's "former 3" gets read by the new server as the "new 3."

Second, type changes. Keep the same number but change the type, and unless the two types share the same wire encoding, values break silently. The varint family (int32/int64/uint32/uint64/bool/enum) is interchangeable, but sint32/sint64 use zigzag encoding and are not compatible with int32.

Third, cardinality changes between optional and repeated, or adding/removing required in proto2. These destabilize parsing of the whole message.

Whether a type change breaks the wire can be judged from this table.

Original typeCompatible change targetsWire type
int32, uint32, int64, uint64, bool, enumInterchangeable (mind value ranges)varint
sint32, sint64Only with each other (not the varint family)varint (zigzag)
string, bytesInterchangeable (only if bytes are valid UTF-8)length-delimited
fixed32, sfixed32, floatInterchangeable32-bit
fixed64, sfixed64, doubleInterchangeable64-bit

Recalling this table to audit every diff is not realistic. So we give it to a machine.

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
If you want to hand .proto edits to an agent but worry about breaking old clients through field-number reuse or type changes, you can now gate that automatically before every push
You can drop a wire-compatibility gate built from buf breaking, reserved declarations, and a field-number reuse check straight into your own CI and git hooks
You'll get a concrete boundary for how much to delegate to an agent versus verify by machine, applied to the fragile territory of schema changes
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

App Dev2026-07-03
Catching Download Size Regressions Before Submission Day — A Weekly Agent Gate for AAB/IPA Size Budgets
Mediation SDKs and bundled assets quietly inflate download size. A design for size ledgers, budget gates, and agent-driven delta attribution using bundletool and App Thinning reports.
App Dev2026-07-02
Before You Let an Agent Own Your Tests — Deciding How Fixtures and Seed Data Live
Agents will happily edit test data until the tests pass. A practical defense built on fixture ownership, deterministic seeds, and anonymized subsets of production data, with working scripts.
App Dev2026-06-30
When Every Antigravity-Written Test Is Green but the Same Bug Comes Back — Field Notes on Measuring Hollow Assertions
Your AI-written tests all pass, coverage is high, yet the same defect returns to production. The cause is over-mocking and tautological assertions. These are field notes on using mutation testing as ground truth to measure what your tests actually protect, and to fix it operationally.
📚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 →