Skip to content

fix(clustering): rename only genuine title outliers, not near-ties - #76

Merged
flvvius merged 1 commit into
mainfrom
claude/retitle-calibration
Aug 27, 2026
Merged

fix(clustering): rename only genuine title outliers, not near-ties#76
flvvius merged 1 commit into
mainfrom
claude/retitle-calibration

Conversation

@flvvius

@flvvius flvvius commented Aug 27, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to #75. The margin-based rename rule over-fired and would have churned published headlines. This recalibrates it against production data.

What the dry run showed

Running the backfill in dry-run mode renamed 52 of 200 events (26%) — far above the 4–6% divergence rate actually observed. The samples explained why:

Două explozii la Damasc, lângă hotelul unde a fost cazat Macron
Explozii la Damasc, lângă hotelul în care este cazat Macron

Same story, reworded. Swapping one for the other on a published, indexed headline is churn, not repair.

The actual discriminator

Calibrating against 26 production clusters showed the rule was wrong in kind, not degree. The gap between winner and incumbent doesn't separate the cases — the incumbent's absolute centrality does:

Case incumbent score verdict
Zelensky → Moscow 0.014 genuine divergence
Oana Țoiu → Nicușor Dan 0.014 genuine divergence
Damen Mangalia shipyard 0.163 same story
Air alert 0.158 same story
Helicopter / cable car 0.086 same story

The two genuinely broken events share essentially nothing with their clusters. The false positives are perfectly representative titles that merely lost to a marginally more central phrasing.

Change

A title is renamed only when all three hold:

  • incumbent < 0.05 — it is a real outlier against its own cluster
  • replacement ≥ 0.05 — the new title represents the cluster rather than being another outlier
  • replacement ≥ 3× incumbent — clear dominance, not a near-tie

Both real divergent events still get renamed; the same-story swaps no longer do.

Testing

339 passed, 4 skipped. Adds the Damascus cluster as an explicit churn regression test, alongside the existing Moscow cluster test that must still fire.

🤖 Generated with Claude Code


Generated by Claude Code

The margin-based rule shipped in #75 over-fired. A dry run of the
backfill renamed 52 of 200 events (26%), and the samples showed why:
most were same-story swaps, e.g. "Două explozii la Damasc, lângă hotelul
unde a fost cazat Macron" replaced by "Explozii la Damasc, lângă hotelul
în care este cazat Macron". That is churn on a published headline, not a
repair.

Calibrating against 26 production clusters showed the discriminator is
the incumbent's absolute centrality, not its gap to the winner:

  Zelensky -> Moscow      incumbent 0.014   genuine divergence
  Oana Țoiu -> Nicușor Dan incumbent 0.014  genuine divergence
  Damen Mangalia shipyard  incumbent 0.163  same story
  Air alert                incumbent 0.158  same story
  Helicopter / cable car   incumbent 0.086  same story

A title is now treated as the outlier only when it shares essentially
nothing with its cluster (< 0.05), the replacement is itself
representative (>= 0.05), and it dominates by 3x rather than edging
ahead. Both real divergent events still get renamed; the same-story
swaps no longer do.

Adds the Damascus cluster as a churn regression test.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012MpkuigW6T4N1exXip6bRp
@flvvius
flvvius merged commit 0454891 into main Aug 27, 2026
1 of 3 checks passed
@vercel

vercel Bot commented Aug 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
news-web Building Building Preview Aug 27, 2026 7:08pm

@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a208f23d-f857-4e88-b954-0e80676361a8


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants