A stability-guaranteed republication of grpc-go.
stablerpc-go replays every grpc-go release from v1.0.5 through v1.79.3
(175 tags, 174 transitions) through an automated AST transformation
pipeline that applies compatibility fixes with the benefit of hindsight.
Every transition is validated with gorelease to prove that no public
API incompatibilities exist. The result is a module at
go.stablerpc.io/grpc that users can depend on with real semver
confidence — something grpc-go has never provided.
grpc-go ships everything — stable core, experimental extensions,
internal utilities — in a single google.golang.org/grpc module at
v1.x. Go's module system treats every release as a stability
commitment, but gorelease flags every single release as
containing incompatible changes. After filtering out the trivial
Version constant noise, 43% of releases contain real, substantive
API breaks — in minor and patch releases.
The damage extends beyond grpc-go's own users. Projects like OpenTelemetry, etcd, and Kubernetes act as transmission vectors: they responsibly update grpc-go for security, which forces the update on their downstream users, who break. See STABLERPC.md for the full argument.
Two deliverables, in order of reusability:
-
The Playbook (PLAYBOOK.md) — A verified-complete catalog of 16 techniques for absorbing every category of Go API breaking change without violating semver. Includes a decision tree, worked examples from the Go standard library and OTel SDK, and a breaking change registry mapping every grpc-go root-package break to its fix. Reusable by any Go project facing the same problem.
-
The Stabilized Module —
go.stablerpc.io/grpc, a republication ofgoogle.golang.org/grpcwith a stabilized API. Migrating from grpc-go is itself a breaking change — the API is deliberately different, redesigned with hindsight — but once you're on stablerpc-go, zerogoreleaseincompatibilities across 174 transitions. Stable forever after. Generated deterministically by the replay pipeline.
An agent-driven convergence loop:
Clean slate → Replay all 174 transitions → Check results
↑ |
└──── Fix breaks (patches, YAML, toolkit) ←────┘
Each transition: extract grpc-go tag → apply AST transforms (module path rewrite, stability fixes) → apply version-layered patches → build → commit → run gorelease against previous version.
The process iterates until convergence — a fixed point where the full history replays with zero incompatible changes.
Iteration 24 — fully converged:
| Metric | Result |
|---|---|
| Root-package incompatible | 0 across 174 transitions |
| Subpackage build errors | 0 |
| v1.x subpackage incompatible | 0 |
| v0.x subpackage incompatible | 58 (expected experimental churn) |
| Analysis failures | 1 (known third-party rate limiting) |
| Stability fixes applied | 54 automated steps per version |
| Patch files | 45 across 26 version directories |
| Downstream validation | 5 OTel repositories build and test ✅ |
See docs/RETROSPECTIVE.md for the comprehensive guide to the techniques, decisions, and results.
# Prerequisites: Go 1.25+, gorelease
git clone <repo-url>
cd stablerpc-go
# Clone grpc-go source (required)
git clone https://github.com/grpc/grpc-go.git
# Spot-test a single transition (~5 min)
bash cmd/run-replay.sh v1.65.0 v1.65.1
# Full replay (~4 hours, 174 transitions)
bash cmd/run-replay.sh
# Monitor progress
tail -f /tmp/replay-latest.log
# Check results
bash cmd/check-results.sh
bash cmd/detail-results.shSTABLERPC.md The argument: problem, solution, module design
PLAYBOOK.md Stability technique catalog (primary deliverable)
docs/
RETROSPECTIVE.md The retrospective rewrite manual
evidence/ANALYSIS.md The problem, gorelease data, Connect comparison
evidence/CASE_STUDIES.md Case studies (etcd, K8s, Istio, etc.), severity scores
internal/ Working notes: iteration log, architecture, tooling
cmd/
run-replay.sh Full clean replay of all transitions
stablerpc-step.sh Transforms one grpc-go version
check-results.sh Summarize gorelease results
detail-results.sh Show incompatible changes in detail
stablerpc-toolkit/ Go AST transformation toolkit
instructions/
stability-fixes.yaml 54 fix steps, version-gated, condition-evaluated
patches/ Version-layered .go compatibility shims
v1.2.0/ ... v1.69.0/ Applied cumulatively: all patches ≤ version
results/gorelease/ gorelease output for all 174 transitions
gomod-synth/ Synthetic go.mod for pre-module versions
output/ Generated stablerpc-go repo (not committed)
| Document | Purpose |
|---|---|
| STABLERPC.md | The argument: problem, solution, module design |
| PLAYBOOK.md | Technique catalog — how to absorb any breaking change |
| docs/RETROSPECTIVE.md | The comprehensive retrospective rewrite manual |
| Document | Purpose |
|---|---|
| ANALYSIS.md | The grpc-go problem, quantitative gorelease data, Connect comparison |
| CASE_STUDIES.md | Case studies (etcd, Kubernetes, Istio, etc.), severity scores |
The docs/internal/ directory contains working documents
from the development process: the iteration log, architecture notes, tooling
examination, and session summaries. These are kept for historical interest
but are not polished for a general audience.