Rename leak signature to leak fingerprint - #2938
Merged
Merged
Conversation
The hash that identifies a leak was called its signature everywhere: the `signature` property of `Leak` and `LeakTrace`, the `Signature:` line of a printed heap analysis, the `unreadLeakSignatures` event field, the leak table's column, and the explorer's leak row. Two problems with the word, both of which cost a newcomer time. In a Kotlin or Java codebase "signature" already means a method signature, and on Android it also means the signature an APK is signed with — both of which appear in this repo, in `HprofRecord.methodSignatureStringId`, in `COMPRESS_SIGNATURE`, in the release workflow, and in the change log entry about a constructor. And it never said what the hash is for, which is that two leaks with the same one are caused by the same bug. "Fingerprint" says content-derived identity and collides with nothing here. The hash itself doesn't change, so a leak keeps the string it had and reports across the upgrade still line up. Values are `leakFingerprint`, prose is "leak fingerprint", and the function names that already say Leak take `ByFingerprint`, so nothing reads `leak.leakFingerprint` or `retrieveLeakByLeakFingerprint`. The `leak.signature` column becomes `leak.fingerprint`, mirroring how the old schema named the column after the concept and the index after both. Renaming a column needs SQLite 3.25, i.e. API 30, so the table is copied over in a version 26 migration rather than the database being recreated, which would throw away the stored leak history. `DatabaseMigrationTest` upgrades a committed v24 database, so it covers the migration; it passes on API 24 and on API 36, either side of the SQLite version where ALTER TABLE RENAME started rewriting other tables' foreign key clauses. Left alone: every unrelated sense of the word, and the entries of released change log versions, which describe an API that was called `signature` at the time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
dayanruben
pushed a commit
to dayanruben/leakcanary
that referenced
this pull request
Aug 6, 2026
AGENTS.md claimed docs/api was Dokka output committed to the repo. It has been git ignored since 5abae5d ("Prepare 2.9 release", April 2022), which untracked every docs/api file and added the directory to .gitignore in the same commit. Both release guides already have this right: they run `rm -rf docs/api && ./gradlew siteDokka` before `mkdocs gh-deploy` precisely because the directory isn't there. That line sent me looking for a directory to regenerate after a public API change in square#2938, which is the exact failure this file exists to prevent. Moved out of "Things that will bite you" and onto the siteDokka command, next to updateKotlinAbi. Nothing about a generated, ignored directory is surprising once stated, so it isn't a bite; the useful moment for the fact is when you've just changed the public API and are deciding what to regenerate. Kept the half of the warning that still holds — fix the KDoc, not the generated pages. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The hash that identifies a leak was called its signature everywhere:
Leak.signatureandLeakTrace.signature, theSignature:line of a printed heap analysis,unreadLeakSignatureson the analysis-done event, the leak table's column, and the leak row in Shark Explorer. It's now called its leak fingerprint.Why
Two problems with the word, both of which cost a newcomer time.
It's already taken, twice. In a Kotlin or Java codebase "signature" means a method signature, and on Android it also means the signature an APK is signed with. Both senses live in this repo —
HprofRecord.methodSignatureStringId,COMPRESS_SIGNATUREin the JDWP bitmap reader,PNG_SIGNATURE, the notarization step of the release workflow, and the change log entry about a constructor's signature changing. So a reader meets three unrelated meanings of one word, and the leak one is the odd sense out.It never said what the hash is for, which is that two leaks with the same one are caused by the same bug. "Fingerprint" says content-derived identity, matches what Sentry calls the same concept, and collides with nothing here.
The hash itself doesn't change — same input, same SHA-1 — so a leak keeps the string it already had, and a bug report or a dashboard grouped by it still lines up across the upgrade.
Naming rule
Values are
leakFingerprint, prose and user-visible text say "leak fingerprint", and the function names that already sayLeaktakeByFingerprint. So nothing readsleak.leakFingerprintorretrieveLeakByLeakFingerprint.Breaking changes
LeakTrace.signatureLeakTrace.leakFingerprintLeak.signature(and both subclasses)Leak.leakFingerprintHeapAnalysisSucceeded.unreadLeakSignaturesunreadLeakFingerprintsSignature: <hash>in printed outputLeak fingerprint: <hash>unreadLeakFingerprintsis inleakcanary-android-core's ABI, the contractAGENTS.mdsays to break only as a last resort — flagging it rather than assuming it's fine. The ABI diff is exactly these five accessors and nothing else.Database
The
leak.signaturecolumn becomesleak.fingerprint, mirroring how the old schema named the column after the concept and the index after both (leak_signature→leak_fingerprint).ALTER TABLE RENAME COLUMNneeds SQLite 3.25, i.e. API 30, so a version 26 migration copies the table over — create, copy, drop, rename — rather than recreating the database, which would throw away the user's stored leak history.DatabaseMigrationTestupgrades a committed v24 database and then reads it back, so it covers this. It passes on API 24 and on API 36 — either side of the SQLite version whereALTER TABLE RENAMEstarted rewriting other tables' foreign key clauses, which is the failure mode this migration is shaped to avoid.The standalone
leakcanary-app's SQLDelight schema is renamed too. It has no migration files, which is unchanged by this.Left alone
methodSignatureStringId,FixedWindowCallback,ByteArrayTimSort), code signing (the release workflow and its doc), the JNI descriptorCOMPRESS_SIGNATURE, PNG magic bytes,EqualsOnSignatureLinein the detekt config, and the// TODO Enforce package signatureinLeakUiAppClient.signatureat the time; rewriting them would make them claim otherwise. Only the## Unreleasedsection is updated.Verification
./gradlew build— green, which includescheckKotlinAbiand detekt../gradlew :leakcanary:leakcanary-android-core:connectedDebugAndroidTest— 27 tests green on API 36, and the 7DatabaseMigrationTesttests green on API 24 as well.🤖 Generated with Claude Code