16 weeks, 27 repos, 7728 commits - the git history of RektRadar

What four months of full-time Claude-paired building actually looks like on the git log : four phases, twin scaffolds, a sunset that was silent, and one repo the agents quietly colonized.

This week we pulled the git log on every repository we’d shipped since the day RektRadar started. The shape of what came back was interesting enough to write down, because it didn’t look like the story we would have told from memory.

7728 commits across 27 repos in 16 weeks. Bare clones with --filter=blob:none in parallel, log extraction per repo, then sub-agents narrating one phase each. The numbers exist, the patterns the numbers describe are mostly invisible from inside the build.

Four phases, ranked by what was being decided

Phase 1 - Fondations (Jan 31 → Feb 28)

The first commit landed on infra-eth-node on January 31. For the first two weeks, infra-eth-node was the de-facto monorepo : log-ui, factory-watcher, and contract-analyzer all show up on the same day as miror repos with matching "second commit" / "third commit" messages, but the actual code stayed in the infra repo until February 17. On that one day - cfe2f5e, 9c76527, 9b3ac97 - every service got its own notify-deploy workflow and the build/push moved out of infra-eth-node. Same day, hexagonal refactor (1c19fe8, 03268db, d64089e, 1ead24d) landed across three services with matching timestamps. The TypeScript conversion finished by evening (9ec4907, d5ed2e0).

Multi-node was decided early. eth2 (Hetzner, then-frankfurt) was added on Feb 8 (c857a7a). eth3 (Varsovie) on Feb 9 (d5901a5), with Nethermind 1.36.0 and Lighthouse v8.1.0 frozen from the start. The role split - eth1 watches and DB, eth2/eth3 mempool sources - was committed before the service repos were independent.

By the end of February, 13 backend services were live, each as its own Ansible role, each pushing through SonarQube and a Copilot review.

Phase 2 - Produits (Mar 4 → Mar 21)

This is the phase nobody can tell from memory : on March 4 at 22:33 UTC, rektradar-app (ade8c97) and rektproof-app (fff9e53) were created 23 seconds apart. Identical scaffold, identical port pattern, identical tests. For three days the commits stayed twin - every change on rektradar had a mirror on rektproof within minutes. The first divergence was March 7 : 731955f “restructure pricing tiers + restrict contract-maker to admin” on one side, a7debcc “restructure pricing tiers for certification focus” on the other.

auth-middleware arrived on March 6 (2ebcdaf, 117 tests on day one). Six things in one middleware : JWT, Keycloak RSA JWKS, SIWE wallet auth, ERC-20 balance gating, Stripe sub gating, rate limiter per tier. The two SPAs both routed through it via /api/auth/check-access and /api/auth/resolve-access.

The anomaly of this phase was oracle-updater. 193 commits in 30 days, 90 of which were the same agent-retry PR fixing 3 survived mutants in the same domain model. The repo was too easy to saturate - one domain model, no integration boundary - and the agents kept finding it the path of least resistance. On March 24, 6466a49 purged 106 redundant coverage-boost test files, an implicit admission that the work had been spinning. The repo died silently on April 1.

Phase 2 closed with platform-api on March 21 - create-service.sh turned into a real API monolith. By then the template that produced 14 backend services and 2 SPAs in seven weeks could be invoked over HTTP.

Phase 3 - Channels (Apr 25 → Apr 29)

Five days, four acquisition channels. April 25 at 14:43, create-service.sh produced rektradar-telegram. Two hours later, grammY replaced the stub. At 16:09, rektradar-discord scaffolded from the same template. At 18:15, both bots got /recent in twin commits. Two days later, PostHog tracking on both. The shared business logic lived in a single Postgres table both bots queried directly - no second API tier, no shared client library.

On April 29, the marketing surface migrated to Astro 5 + Cloudflare Pages. rektproof-site scaffolded at 17:11 (577d28e), rektradar-site six minutes later (bb02176). Both pulled the same outline : analytics, IndexNow keyfile, sitemap-index, Pages Functions proxy to the app API.

There’s a quieter move from this week, worth flagging. On April 30, the only public repository on the entire platform - awesome-ethereum-scam-detection - was created with two commits. A curated awesome-list. README format. RektRadar listed first under “Real-time Detection Tools” with a hard backlink. Same 24-hour window, the blog published “RektRadar vs Etherscan / TokenSniffer / GoPlus” comparisons (3c47a1b). Public README points at the site, site compares itself to the tools the README lists. Sandwich SEO at zero marginal cost.

Phase 4 - Consolidation (May, ongoing)

May is where the platform decided which of the two products it really was. RektProof totals about 10 commits in the month : c3eddca on rektproof-app on May 1, then six on rektproof-site that stop at the favicon fix on May 3. RektRadar accumulates around 380. Ratio 1 to 38.

There’s no “deprecate” commit. The sunset is by attrition. The visible cleanup came three weeks later : on May 23, 6141a33 removes every RektProof mention from the landing, and cc4fd04 removes the footer link from the SPA the same day.

Meanwhile rektradar-site writes 273 commits in May alone. Breakdown : 37 content(blog), 20 fix(nav), 14 feat(landing), 13 feat(blog), 11 feat(redirects), 10 feat(seo). Eight tokens deep-dived (KEKIUS, OPTIMUS, MOODANG, Unicat, $CLAUDE, GXAG, $XRP, etc.). Two long-tail landings (/list-of-fake-crypto-exchanges, /rug-pull-checker). Hreflang, WebSite+SearchAction schema, sitemap-index, HTML /scam-index. Free tier becomes unlimited, free trial drops the upfront card.

The new tooling of May is cockpit. First commit May 5 at 21:22 (d87d55e), 82 commits in 14 days. PostHog funnel reads with internal-traffic filters, nginx 5xx via OpenSearch, anomaly detector, Reddit + Twitter integrations, deploy to cockpit.rektradar.io behind oauth2-proxy. It replaces six tmux terminals.

A symptom : one component on the app - QueuedScanBanner - eats nine consecutive iterations between 42c3ba3 and 3b91474 (a revert). When the build moves into consolidation, the same surface gets rewritten until it settles.

The two surprises

1. One repo died, and we missed it for a month

oracle-updater was never killed. It was just left running while the agent retry loop kept fixing the same three mutants until someone - me - noticed the diff between “active commits” and “useful work” had become massive. The lesson is operational : if you point AI agents at a repo with a single narrow domain model and no downstream integration to break, they will exhaust the search space on that domain model before they touch anything harder. Watch for repos where 90 commits out of 193 carry the same message.

The fix is upstream - agent-retry caps at two attempts per failure and copilot-review-action caps at two fixes per PR. But that constrains a single PR run. It doesn’t constrain how many new PRs the same agent will open against the same domain. The discipline you actually need is at the issue level : tasks that touch only domain code, with no integration acceptance criteria, are bait.

2. Twin scaffolds signal coupling that the architecture diagram doesn’t

rektradar-app and rektproof-app were nominally two separate products. Their first 100 commits were jumeaux to the minute. The two bots ship the same logic via direct Postgres reads. The two sites share the Astro template and the Cloudflare Pages config. The architecture document calls them four independent services. The git log calls them two pairs of one.

Twins in the timeline tell you the real split. They also tell you what will be hard to delete. RektProof is sunsetting cleanly because there’s a twin product still running - every file we deleted from the landing this week had a corresponding file already maintained on rektradar’s side.

How the analysis ran

The pipeline that produced this post took about two hours :

  1. git clone --bare --filter=blob:none on all 27 repos in parallel into /tmp/repo-history/<repo>.git (~6 concurrent clones, no blobs so it’s fast).
  2. Per-repo stats : git log --all --reverse --format='%aI' for first/last commit, wc -l for total, cut -c1-7 | sort | uniq -c | sort -rn | head -3 for top months. Bash, under a minute.
  3. Four sub-agents in parallel, one per phase, each reading the messages of the commits in its window. Output : four markdown files, each 400-700 words.
  4. Manual aggregation. The “what surprised me” section was written from the raw output, not from the original ambition.

If you’re building solo with AI agents and want to do this on your own repos, the only piece that took real thought was step 3 - narrating from commit messages is fragile because the messages can lie or be terse. Two of the four agents had to be re-prompted to actually git log instead of guessing.

What’s missing

The git log doesn’t capture the decisions that produced the commits. The pivot RektProof → RektRadar shows up as a ratio (1 to 38 in May) but doesn’t explain itself. The choice of three nodes on three different providers shows up on Feb 8 as a fact, not a justification. The discipline that made the agent-retry loop bounded was added after oracle-updater had already died.

If you came here looking for a build-in-public recipe, the recipe is mostly :

  • a service template that scaffolds infra + tests + CI + Ansible role + service registry in one command,
  • twin scaffolds for paired products, accepting that you’ll delete one of the twins later,
  • agents you can trust on bounded tasks but not unbounded ones,
  • a cockpit that reads your funnel back to you so the consolidation phase isn’t blind,
  • and the willingness to let a side product sunset by attrition instead of by ceremony.

The whole stack is sitting on three Ethereum nodes, ~30 containers, two Postgres clusters, eighteen Ansible roles. The audit took two hours because the platform was already structured the way it is. Building solo with this stack, the math changed - but the math only changed because the structure was set up the day the first multi-node commit landed.