CCLearn

Track survival rate, not acceptance rate

Judge a Claude Code rollout by how much of the generated code is still in the tree weeks later, not by the accept rate on the dashboard — which by its own documentation stops counting the moment a suggestion is accepted.

docs corroborate

The official documentation describes the mechanism this relies on. The technique itself is community practice.

What this costs you if it is wrong

Survival rate needs a window you pick arbitrarily, and it penalises legitimate refactoring and deletion — treat it as a direction to look, never as a number anyone is bonused on. Computing it means running git blame across the working tree, which is read-only but slow on large repos. The 94% cache-hit figure is GitHub's own API harness, not a Claude Code CLI number, and no official doc publishes a target hit rate at all.

Someone above you has asked whether Claude Code is worth what it costs. You open the analytics dashboard and it hands you two headline numbers: suggestion accept rate and lines of code accepted. Both go up and to the right. Both are activity metrics, and one of them is documented to be blind in exactly the place your skeptic will poke.

What the dashboard actually counts

The docs are unusually candid about this. From the analytics page's definition of lines of code accepted: it "excludes rejected suggestions and does not track subsequent deletions."

That last clause is the whole tip. A line Claude wrote, that you accepted, that you deleted forty minutes later because it was wrong, is counted once and never decremented. You can post a superb accept rate while producing churn.

MetricWhere it comes fromWhat it can't see
Suggestion accept rateEdit / Write / NotebookEdit permission decisionsWhether the accepted edit was any good
Lines of code acceptedSame, tallied in linesDeletions after the fact — stated explicitly in the docs
claude_code.lines_of_code.count (OTel)Emitted with type: added or removedWhether a removed line was Claude's own from an hour ago
Lines of code with CCMerged-PR attribution via the GitHub appAnything that never reached a merged PR

Survival rate is the metric that asks the next question: of the code Claude wrote in some window, how much is still in HEAD?

The docs already ship a weak version of it

Worth knowing before you build anything: the contribution-metrics side of the dashboard is already a survival filter, just a short one. Per the PR attribution section, only merged PRs are analysed, sessions are matched in a window running 21 days before to 2 days after the merge, and "code substantially rewritten by developers, with more than 20% difference, is not attributed to Claude Code."

So "Lines of code with CC" is roughly survival-to-merge. What it does not give you is survival-past-merge, which is where the churn you actually care about hides.

Approximating it locally

Nothing in Claude Code computes survival for you. A crude repo-level proxy: take the lines added in a window and ask how many of them git blame still attributes to those commits today.

bash
#!/usr/bin/env bash
# Proxy survival rate for a window of commits. Read-only.
set -euo pipefail
WINDOW="${1:-90 days ago}"

git rev-list --since="$WINDOW" HEAD | sort > /tmp/win-shas.txt

ADDED=$(git log --since="$WINDOW" --numstat --format= \
  | awk '$1 ~ /^[0-9]+$/ { a += $1 } END { print a+0 }')

ALIVE=$(git ls-files \
  | xargs -n 200 git blame --line-porcelain -- 2>/dev/null \
  | awk '/^[0-9a-f]{40} /{ print $1 }' \
  | sort | join - /tmp/win-shas.txt | wc -l)

echo "added in window:   $ADDED"
echo "still at HEAD:     $ALIVE"
echo "survival proxy:    $(( ALIVE * 100 / (ADDED > 0 ? ADDED : 1) ))%"

Write it to a file and run it with bash. Do not paste the loop into an interactive zsh prompt.

This is repo-wide, not Claude-specific. To narrow it to Claude's output you need an attribution signal: filter /tmp/win-shas.txt to the merge commits of PRs GitHub labelled claude-code-assisted, which the docs say you can find with a normal PR search on that label.

The second signal: your cache hit rate has a floor

The same community talk this tip comes from offers a harness-builder's number: GitHub reportedly runs above a 94% prompt cache hit rate and treats a fall to roughly 70% as a bug in how prompts are assembled, not as variance.

The docs give you the instrument but not the threshold. Run /usage and read the Prompt cache (main) line: it reports the request count, the share of input tokens served from cache, the miss count, and whether the cache is warm. Both halves of it are recent arrivals — the line itself "Requires Claude Code v2.1.251 or later", and the named likely cause for the last miss, such as likely cause: tool definitions changed, "requires Claude Code v2.1.260 or later". What it gives you is one session's summary, which is the wrong shape for a question about a rollout. For visibility across an organization the docs point at the OpenTelemetry exporter instead, which reports cache read and creation tokens per user and session: claude_code.token.usage is broken out by a type of "input", "output", "cacheRead" or "cacheCreation", and you compute the ratio yourself. The prompt-caching page also lists what invalidates a prefix: switching model, switching effort level, enabling fast mode, changing output style, resuming across an upgrade.

Nowhere do the docs publish a target percentage. Treat 94/70 as one large team's operating band, not a spec.

What is unverified here

Be clear about which parts of this rest on what.

  • Docs-confirmed: that lines-accepted ignores later deletions, that accept rate is a permission-decision count, that contribution metrics only see merged PRs with a 21-day window and a 20% rewrite cutoff, and that /usage reports a cache hit ratio.
  • Not in the docs at all: the word "survival", any recommendation to measure it, and any target cache hit rate. The corpus is silent.
  • Community attribution: the framing and both cache figures come from a machine-made transcript of a Code w/ Claude 2026 talk on building at GitHub scale, circulated in a community repo. Nobody here has checked that transcript against the recording, so treat the exact numbers as reported speech and the argument as the durable part.

What would settle it: run the script above on a repo that has been using Claude Code for a quarter, split by claude-code-assisted label, and compare the resulting survival figure against that period's dashboard accept rate. If they track each other closely, the tip is a distinction without a difference for your team. If they diverge, you have found the churn the dashboard is documented not to show you.

Checkpoint

  • Which dashboard metric is documented to ignore deletions, and what does that mean for an accept rate you are about to put in a slide?
    Show answer

    Lines of code accepted. The analytics page defines it as excluding rejected suggestions and not tracking subsequent deletions, so a line Claude wrote, you accepted, and you deleted forty minutes later is counted once and never decremented. For the slide: both headline numbers measure activity, and a superb accept rate is fully compatible with churn — accept rate is a tally of Edit / Write / NotebookEdit permission decisions and cannot see whether the accepted edit was any good. Present them as adoption rather than value, or your skeptic pokes the exact hole the docs already admit to.

  • Why is "Lines of code with CC" already a partial survival metric, and where does its window stop?
    Show answer

    Because the contribution-metrics side only analyses merged PRs and drops work developers substantially rewrote — more than a 20% difference is not attributed to Claude Code — so it is already filtering for code that survived review. Its window stops at the merge: sessions are matched from 21 days before to 2 days after it, and nothing afterwards is observed, which leaves survival-past-merge exactly where the churn hides. If the GitHub integration is on, put it beside "Lines of code accepted" before building anything custom — a wide, widening gap between them is the same signal for free.

  • What does the Prompt cache (main) line in /usage tell you that a raw token count does not?
    Show answer

    A ratio and a state rather than a total: the request count, the share of input tokens served from cache, the miss count, and whether the cache is warm — plus, on newer builds, a likely cause for the last miss such as likely cause: tool definitions changed (the line itself requires Claude Code v2.1.251 or later, the cause v2.1.260 or later). It is one session's summary, which is the wrong shape for a rollout question; across an organization the docs point at the OpenTelemetry exporter instead, where claude_code.token.usage is broken out by a type of "input", "output", "cacheRead" or "cacheCreation" and you compute the ratio yourself. No official page publishes a target hit rate at all — the 94%/70% band is reported speech from a machine-made community transcript, unchecked against the recording.

Where this came from

Official pages that back this