Your last runbook edit was 412 days ago

YOUR DOCS HAVE A HALF-LIFE

Every runbook, ADR and README starts decaying the moment it's merged. HALFLIFE measures the rate. Point it at a repo and get a decay curve for every document you own — which ones are still true, which are lying to your on-call engineer at 3am.

Read-only access. 90-second scan. No agent to install.

Decay curve — payments-svc

Live

Documentation accuracy decay curve for payments-svc Accuracy falls from 100 percent at merge to 50 percent at day 96, the measured half-life, then continues toward 11 percent at day 300. The 50 percent trust threshold is crossed at day 96.
Half-life 96d
Docs past t½ 61%
Drifted this wk 23

Ramp cut incident MTTR by 34%

Vercel found 1,204 dead runbook steps

Linear t½ improved 96d → 287d

Sentry retired 38% of its wiki

Retool onboarding ramp −11 days

Fly.io caught a stale failover doc pre-incident

03

The mechanism

No LLM guesswork · deterministic diffing

Doc rot isn't a writing problem, it's a referential integrity problem. A runbook is a set of claims about a system. HALFLIFE extracts those claims, binds them to the code they describe, and watches the binding break.

STAGE 01

Bind claims to code

We parse every doc into discrete, checkable assertions — a command, an env var, an endpoint, a file path, a threshold — and anchor each one to a symbol in your AST. Not a keyword match. A real binding.

bind · runbooks/failover.md

L14 claim "run pg_failover --zone=b"

└─ bound → cmd/failover.go:88

L27 claim "timeout is 30s"

└─ bound → config/db.yaml:12

STAGE 02

Watch the binding break

Every merge to main re-checks all bindings. When the code moves and the doc doesn't, that's a drift event with a timestamp — the raw material for a decay rate.

drift · main@a3f19c2

DRIFT config/db.yaml:12

was timeout: 30s

now timeout: 5s

→ failover.md:27 now false

3 docs invalidated by this commit

STAGE 03

Fit the curve

Drift events over time give each doc — and each team — an exponential decay constant. That's the half-life: the number of days until half a document's claims are false.

fit · payments-svc

n=1,847 drift events / 18mo

λ = 0.00722 day⁻¹

t½ = 96 days (r²=0.94)

61% of docs past t½

04

One org, one year

364 documents · scanned nightly
Documentation decay map for a 364-document corpus A grid of 364 cells, one per document, arranged as 52 weeks across and 7 document classes down. 43 percent are still accurate, 23 percent are aging, 15 percent have passed their half-life, and 20 percent are critical — more wrong than right. Decay concentrates in the older left-hand side and in the fast-decaying runbook rows at the top.
Accurate 43% Aging 23% Past t½ 15% Critical 20% Each cell is one document. Rows are doc classes; columns are weeks since last verified.
05

The decay ledger

Sample org · 340 engineers · 12,441 docs

This is what a scan returns. Sorted by what will hurt you first — not by folder, not alphabetically. Expand a row to see the reasoning.

Runbooks decay fastest because they encode the most volatile layer of your system: CLI flags, dashboard URLs, alert thresholds, on-call rotations. A 41-day half-life means the average runbook is more wrong than right within six weeks of being written — and nobody notices until the pager fires.

top invalidated claims

kubectl ctx prod-us-east-1 (renamed 88d ago)

alert threshold p99 > 400ms (now 250ms)

escalate to #team-infra (archived)

The setup section is the part that rots. Dependencies bump, a service gets a new required env var, the seed script moves. HALFLIFE flags the specific line rather than the document, so the fix is a two-minute PR instead of a rewrite nobody volunteers for.

README.md · setup block

nvm use 20

make seed-db → target removed 34d ago

missing: STRIPE_WEBHOOK_SECRET

ADRs decay slowly but fail loudly. The document stays accurate about what was decided while the constraints that justified it quietly expire. HALFLIFE tracks the premises — the load numbers, the vendor limits, the team sizes — and tells you when a decision's foundation is gone.

ADR-0034 · premise check

premise "peak 2k req/s"

→ actual: 19.4k req/s

premise "team of 4"

→ actual: 23 contributors

verdict: revisit

We include this row because it's the control. Generated docs have a long half-life by construction — which is the whole argument. Docs rot in proportion to how far they sit from the source of truth. HALFLIFE measures that distance so you know which docs to generate, which to test, and which to delete.

openapi.yaml · derived

✓ 412/418 claims bound

source-derived · regenerates on merge

6 hand-written examples drifting

06

Field report

Ramp · platform infrastructure
We didn't buy this to write better docs. We bought it because our incident review kept producing the same action item — "update the runbook" — and we had no way to know which of the other four hundred runbooks were already wrong. Now that's a number on a dashboard, and it goes down.
Devi Raman Staff Engineer, Platform Infrastructure
Ramp · 340 engineers · adopted Q2 2025
34% Lower MTTR on incidents touching a HALFLIFE-verified runbook
96 → 287d Median doc half-life after two quarters
2,910 Stale docs retired rather than rewritten
07

Cost

Per repo, not per seat

We charge for repos analysed, not engineers employed. Adding a reader to a doc tool shouldn't cost money — that's how the docs got stale in the first place.

Single repo
$0 / forever

One repository, full decay ledger, unlimited readers. Enough to prove the number to your team.

  • Full decay ledger + half-life fit
  • Drift alerts on merge to main
  • Unlimited viewers
  • Org-wide rollup
  • Self-hosted runner
Start scanning
◆ Org
$240 / repo / year

Every repo, one rollup, and the half-life number your VP Eng actually wants on the quarterly slide.

  • Everything in Single repo
  • Org-wide half-life rollup by team
  • Self-hosted runner — code never leaves your VPC
  • SSO/SAML, SOC 2 Type II report
  • Decay budgets enforced in CI
Scan your org
08

Objections

The ones you're already thinking

No. The binding layer is deterministic — tree-sitter parses your source, claims are anchored to real AST nodes, and drift is a diff, not a judgement. A model is used in exactly one place: extracting candidate claims from prose, where you review the extraction before it counts. If a doc is flagged, we can show you the commit that invalidated it.

On the free tier, we clone read-only into an ephemeral sandbox and destroy it after the scan; nothing is retained but the binding graph. On Org, the runner is a container you host — it pushes only anonymised drift events to us. SOC 2 Type II report available under NDA.

Both are supported, and they're usually where the worst decay lives — median half-life for wiki-hosted runbooks is 29 days, versus 41 for in-repo. Distance from the source of truth is the variable that matters, and a wiki is further away.

You delete most of them. That's the honest answer and it's the outcome we optimise for — the median customer retires 38% of their doc corpus in the first month. A smaller set of true documents beats a large set of plausible ones. The ledger is sorted by blast radius so you start where it matters.

You shouldn't, at first — which is why every fit ships with its r² and event count, and why the curve is inspectable down to the individual drift event. Below 200 drift events we label the fit provisional and say so on the dashboard. We'd rather show you an honest wide error bar than a confident wrong number.

Final readout

FIND OUT
BEFORE THE PAGER DOES

Connect one repository. Ninety seconds later you'll have a half-life, a ranked ledger, and a very specific list of documents that are lying to your team.

This page's own half-life: