← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

Goodhart's Law

General Intermediate
debt(d9/e7/b7/t7)
d9 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'silent in production until users hit it' (d9). Detection_hints explicitly states automated=no. The code_pattern examples (100% coverage with trivial assertions, velocity gaming, bug suppression) only become visible when a human notices anomalies in outcomes — often after significant damage to team culture or product quality. No tool in the detection_hints list can catch this; it surfaces only when the metric diverges visibly from the underlying reality it was meant to represent.

e7 Effort Remediation debt — work required to fix once spotted

Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix suggests pairing each metric with a counterbalancing metric, but in practice Goodhart's Law violations are cultural and structural: every process, team norm, performance review, and tooling choice that was built around the gamed metric must be revisited. It is not a single-file fix; it requires changing measurement frameworks, re-educating stakeholders, and redesigning incentive structures across the organisation.

b7 Burden Structural debt — long-term weight of choosing wrong

Closest to 'strong gravitational pull' (b7). The tags (culture, metrics, management) and applies_to (web, cli — broad scope) indicate this affects every engineering team regardless of context. Once a metric becomes a target, every sprint planning, code review, and hiring decision is subtly shaped by it. The burden is persistent and cross-cutting, influencing all work streams, though it stops short of b9 because a team can partially escape it by adopting counterbalancing metrics without a full rewrite.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception field states that more metrics are assumed to equal better measurement, when in fact more targets create more gaming surfaces. This is a well-documented but widely ignored trap: competent developers routinely set up coverage gates, velocity dashboards, and DORA metrics in good faith, only to discover the metric has decoupled from the reality it was measuring. It scores t7 rather than t9 because the law is well-known by name, even if rarely applied correctly in practice.

About DEBT scoring →

Also Known As

Goodhart's Law metric corruption Campbell's Law

TL;DR

"When a measure becomes a target, it ceases to be a good measure" — optimising for metrics corrupts them and misses the underlying goal.

Explanation

Charles Goodhart's observation applies constantly in software engineering: lines of code as a productivity metric incentivises verbose code; code coverage as a quality metric incentivises meaningless tests; story points as velocity incentivises point inflation. The metric was valid as an indicator of the real goal, but once it becomes the target, teams optimise the metric while the real goal deteriorates. The fix: use multiple metrics, change metrics regularly, and focus on outcomes over outputs.

Common Misconception

More metrics means better measurement — more metrics creates more targets to game; a few well-chosen metrics reviewed sceptically are more useful than a comprehensive dashboard optimised toward.

Why It Matters

Every engineering metric — test coverage, deployment frequency, issue close rate, sprint velocity — is vulnerable to Goodhart's Law the moment management starts tracking it.

Common Mistakes

  • 100% code coverage as a quality gate — developers write trivial tests to hit the number without asserting meaningful behaviour.
  • Story points as team performance measure — teams inflate estimates to look productive.
  • Bug count as quality metric — teams stop filing bugs or close them as 'by design'.
  • DORA metrics as performance review criteria — teams game deployment frequency with trivial deploys.

Code Examples

✗ Vulnerable
// 100% coverage target — passes coverage, tests nothing meaningful:
public function testAdd(): void {
    $calc = new Calculator();
    $calc->add(2, 3);   // Line executed — counted as covered
    $this->assertTrue(true); // No assertion — mutation survives
    // Coverage: 100% ✓  Actual quality: 0
}
✓ Fixed
// Focus on the real goal — meaningful assertions:
public function testAdd(): void {
    $this->assertSame(5,  (new Calculator())->add(2, 3));
    $this->assertSame(0,  (new Calculator())->add(-1, 1));
    $this->assertSame(-3, (new Calculator())->add(-1, -2));
}
// Coverage may be 85% — quality is high
// Measure: mutation score, not line coverage

Added 15 Mar 2026
Edited 22 Mar 2026
Views 95
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping T 1 ping F 2 pings S 0 pings S 0 pings M 1 ping T 1 ping W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 3 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W 4 pings T 0 pings F
No pings yet today
ChatGPT 3 PetalBot 1
ChatGPT 11 PetalBot 7 Amazonbot 6 Ahrefs 6 Perplexity 5 Google 5 SEMrush 5 Bing 4 Scrapy 4 Unknown AI 3 Brave Search 3 Majestic 2 Applebot 2 Meta AI 1 Twitter/X 1 Sogou 1
crawler 59 crawler_json 6 pre-tracking 1
DEV INTEL Tools & Severity
🔵 Info ⚙ Fix effort: Low
⚡ Quick Fix
When setting engineering metrics, pair each metric with a counterbalancing metric — code coverage paired with mutation score prevents gaming with empty tests
📦 Applies To
any web cli
🔗 Prerequisites
🔍 Detection Hints
Single metric used as target: 100% code coverage with worthless assertions; velocity as performance metric; lines of code as productivity
Auto-detectable: ✗ No
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Medium Context: File


✓ schema.org compliant