This line is in Flask's app.py:

self_ref = weakref.ref(self) 

Looks over-engineered. Why not just self?

git blame says 2023

$ git blame -w -M -C -C -C -L355,355 src/flask/app.py 0ec7f713 (pgjones 2023-06-11) self_ref = weakref.ref(self) 

"Split the App and Blueprint into Sansio and IO parts." That commit only moved code. Blame tells you who last touched a line, not why it exists.

The real reason is from 2020

$ git log -S"weakref.ref(self)" --oneline 0ec7f713 Split the App and Blueprint into Sansio and IO parts 8efea0cc Break reference cycle created by default in Flask instances. 

The weakref stops a memory leak (#3761). "Simplify" it and the leak is back. You'd only find this if you already suspected a story.

So I built Blot

Blot is a pre-commit hook that has read your git history. It warns when a commit:

  • removes a fix: edits a line a bug fix added
  • re-adds a bug: brings back a line a fix removed
  • forgets a related file: changes A but not B, when they always change together

demo

Or ask about any line. It skips commits that only moved code:

$ blot why src/flask/app.py:355 explained by 8efea0cc 2020-10-03 Break reference cycle ... [bug fix] traced past 0ec7f713 2023-06-11 Split the App and Blueprint ... [refactor] 

Local, no AI, no account. Warns, never blocks.

Staying quiet was the hard part

My first version gave Django 26 warnings per 10 commits. So I replayed the last 500 commits of 5 repos, read every warning, and turned each noise pattern into a rule.

Repo Before After
Flask 1.96 0.10
Express 1.00 0.18
Django 26.30 1.29

The replays also found real moments, like Express reverting the CVE-2024-51999 security patch. Blot flagged it.

Try it

pip install blot-git blot index blot install-hook 

GitHub logo Sym-jay / Blot

A pre-commit check that has read your project's history. Sora the slime warns when a change removes a fix, re-adds a fixed bug, or forgets a file that always changes too.

Blot

CI PyPI

Sora, the Blot slime, sliding back and forth

A pre-commit check that has read your project's history.

Meet Sora, the slime who remembers every fix.

Don't take down a fence until you know why it was put up.

Blot warns you before you commit when your change:

  • removes a fix: deletes or edits code that was added to fix a bug
  • re-adds a bug: brings back a line that a bug fix deliberately removed
  • forgets a related file: changes A but not B, when the two almost always change together

It runs locally, needs no account or AI, and stays quiet unless the history gives it a real reason to speak.

Blot catching a real Flask regression: simplifying self_ref = weakref.ref(self) triggers a removed-fix warning that traces past a 2023 refactor to the 2020 reference-cycle fix

A real run on Flask. Plain git blame points to a 2023 commit that only moved this line; Blot traces past it to the 2020 fix that explains it. (Regenerate with python assets/demo/make_demo.py.)

Status: pre-alpha. Milestones M1 and M2 are…





Pre-alpha. If it cries wolf on your repo, open an issue; that's exactly the feedback I need.

Built with help from Claude (of course, phew); every number here is from a real run.