---
# System prepended metadata

title: Agentic Coding for Tech Debt - gRPC Removal

---

# Agentic Coding for Tech Debt - gRPC Removal

tl;dr;

- With [30 PRs](https://github.com/syjn99/microprysm/pulls?q=is:pr+is:merged+label:gRPC-removal), I finished the [gRPC removal task](https://github.com/OffchainLabs/prysm/issues/15346) in three days with Claude Code.
- This article shares few points that I've been always aware of while working on this project.

## Motivation

- There are several (huge) tasks to improve the overall code quality of the codebase. As [`grep` is the best tool for AI agents](https://newsletter.pragmaticengineer.com/p/building-claude-code-with-boris-cherny) these days, I found debloating the codebase is the key for dev efficiency.
- We have known issues for gRPC removal: https://github.com/OffchainLabs/prysm/issues/15346
- I recently felt kind of "FOMO" on AI tools these days, as all tweets talk about it. I have to get my hands dirty with AIs.

## Process

- Model: Claude Opus 4.6
- Orchestrator: OpenClaw in my idle MacBook Air
- Main tool: Claude Code

### Rule of Thumbs

- Make context window as light as possible. Spawning new Claude Code sessions as much as I can, while preserving some lessons from previous sessions. Make each task as small as possible, so that the agent only focus on a single goal for each session.
- Spend a lot of time planning. `01-plan.md` ([Link](https://github.com/syjn99/microprysm/blob/d41a238048f9b525f1b437cbcf6a445204ce2101/docs/grpc-removal/01-plan.md)) itself acts as a huge whiteboard for AI agents that can track progress themselves while coding.
- Use CI a lot to validate things. Do NOT trust AI agents by looking at diffs. Set up a "baseline" that is (surprisingly) applicable to the human coder as well.
    - For this task, I self-approved a PR that passes Bazel build, test, and e2e (`MinimalConfig` only for performance).
- Maintain `CLAUDE.md` and `.claude` folder as lean as possible.

## Result

- [Full diff](https://github.com/syjn99/microprysm/compare/f6769c17cafe...d41a238048f9) shows 36,673 lines are deleted in net.
- I mostly didn't monitor in front of my laptop: There is a private discord server that acts as a gateway to my OpenClaw agents, and I set up the pipeline. Not a fancy tech, cron-based instruction works well.
    - e.g., "See `plan.md` and do Phase X.Y. Do NOT code yourself, you should spawn a sub-agent with `spawn-agent.sh`. Spawn a separate cron job that monitors the session that you spawned, and if it ends, push it to the origin and open a PR with detailed description."
    - e.g., "Keep monitoring PR #Z, see if CI passes. If CI fails, spawn a fixing agent. Re-run if 'Bazel test' is killed with OOM(*Note: This is quite annoying when you run the CI on free-tiered Github cloud which only has a 7GB memory*). If CI passes, merge the PR and set up a new job for Phase X.Y."


## What's Next?

Here are stuffs on my head right now:

- Kurtosis set-up: Extension from my [previous experiment](https://github.com/OffchainLabs/prysm/pull/16082).
- `*.proto` removal: This is quite tricky. As gRPC **will** be (surely) removed in the future, we don't need `*.proto` files; we can replace them with native Go structs. I guess this is also related with the sub-issues for [gRPC removal issue](https://github.com/OffchainLabs/prysm/issues/15346).
    - First of all, I think a tool like `jsongen` is needed. `jsongen` will take a Go struct (now, structs defined in `*.pb.go`) as an input and then results `MarshalJSON` (and other methods). I have a working code generation tool for this but need more time to validate it with myself.
    - We can do this gradually: Starting from the leaf types like `VoluntaryExit`, `Eth1Data`, etc.
    - I believe this will also improve the node performance and API response time as we don't need to allocate an extra memory for dealing with proto object.

---

## Miscellaneous

- [PR #1](https://github.com/syjn99/microprysm/pull/1) adds three actions that I think the most important validation: using Bazel, build, test, and e2e. It is super slow to run an action on [custom container](https://hub.docker.com/r/syjn99/bazel-toolchain) (that has all toolchains for Bazel build), but it works.
- `ethereum-package` needs some change, as it expects gRPC port (`4000` by default) to be opened. The branch `prysm-grpc-removal` ([Link](https://github.com/syjn99/ethereum-package/tree/prysm-grpc-removal)) includes a commit that actually works on my machine.
