-
Notifications
You must be signed in to change notification settings - Fork 0
0005 hamming jellyfish divergence
github-actions[bot] edited this page Aug 15, 2026
·
3 revisions
Status: accepted · Date: 2026-08-01
The brief maps Hamming to jellyfish.hamming_distance and Jaro/Jaro-Winkler to
jellyfish.jaro*. While validating, we found that jellyfish 1.2.1 diverges from
the standard definition on ≈ 5% of the corpus (Hamming: 62/1241), always on
degenerate strings containing combining marks / emoji / mixed scripts. The same
phenomenon affects jaro_similarity and jaro_winkler_similarity on those same
inputs (the exact count is recorded in each oracle's jellyfish_divergences
metadata).
Investigation:
- It is not a byte-level (UTF-8) comparison:
hamming('é','e')is 1 in jellyfish, 2 in bytes. - It is not NFC normalization: normalizing before comparison doesn't change the agreement rate (1179/1241 either way).
- For all "normal" inputs (ASCII, simple accents, equal-length codes — the real use of Hamming), jellyfish coincides with the standard definition.
The exact cause (behavior of jellyfish's Rust core on combining marks) was not pinned down, and reproducing it would mean copying an unspecified quirk.
-
Implement the standard definition (Hamming: differing positions + length
difference; Jaro/Jaro-Winkler: the classic algorithm with a 0.7 boost threshold
for Winkler), over code points or UTF-16 units per
TextElement. -
Generate each oracle from an explicit reference of that definition
(
_hamming_reference,_jaro_reference,_jaro_winkler_referenceintools/generate_oracles.py), not from jellyfish's output. The generator counts and records the number of jellyfish divergences (jellyfish_divergences) for traceability. -
Anchor jellyfish parity on sane inputs via hand-written test cases
(
[InlineData]) whose values are exactly jellyfish's (real names: MARTHA/MARHTA, DWAYNE/DUANE, DIXON/DICKSONX…).
-
Hamming.Distance(and Jaro/Jaro-Winkler) are correct per the definition and coincide with jellyfish everywhere jellyfish computes a standard result. - The divergence is explicit, measured and versioned, in line with §5 of the brief ("either replicate, or document the divergence").
- 0001-target-framework
- 0002-unicode-comparison-unit
- 0003-provenance-and-licensing
- 0004-levenshtein-myers-backlog
- 0005-hamming-jellyfish-divergence
- 0006-ratcliff-autojunk
- 0007-metaphone-scope
- 0008-italian-enza-nltk-divergence
- 0009-sample-consumes-a-local-feed
- 0010-stop-word-list-provenance
- 0011-persistence-format
- 0012-per-package-versioning
- 0013-sentencepiece-parity-scope
- 0014-precompiled-normalizer
- 0015-sonar-rules-in-the-build
- 0016-metrics-package-placement
- 0017-bpe-parity-scope
- 0018-multiclass-roc-auc-parallelism-is-opt-in
- 0019-the-net-analysers-run-in-the-build-too
- 0020-normalize-is-a-projection-not-a-parameter
- 0021-multioutput-is-a-method-not-an-enum
- 0022-added-token-matching-flags
- 0023-byte-level-decode-substitutes
- 0024-weighted-median-averages-within-scikit-learns-epsilon
- 0025-quickselect-replaces-a-full-sort-for-the-median
- 0026-r2-and-explainedvariance-split-their-undefined-cases-differently
- 0027-r2-and-explainedvariance-vectorize-only-a-single-output
- 0028-log1p-is-kahans-identity-not-math-log-1-plus-x
- 0029-balanced-accuracy-adjusted-is-left-to-ieee-754-at-the-edge
- 0030-cohen-kappa-keeps-scikit-learns-expected-matrix-orientation
- 0031-nosamplecorrect-mirrors-numpys-float64-upcast
- 0032-fbeta-substitutes-tp-predicted-and-support-algebraically
- 0033-compensated-sum-is-neumaiers-variant
- 0034-dropout-is-refused-for-want-of-a-user
- 0035-a-null-pre-split-is-removed-with-invert-not-isolated
- 0036-a-member-may-ship-without-an-oracle-if-it-says-so
- 0037-the-guards-run-before-the-commit
- 0038-the-gate-confronts-an-exception-tag-with-the-page-that-documents-it
- 0039-mutual-information-returns-zero-on-an-empty-input
- 0040-a-curve-is-a-sealed-class-per-curve
- 0041-one-sample-file-per-public-class
- 0042-phonetic-encoders-refuse-a-null-word
- 0043-the-equality-table-is-sized-to-the-pattern
- 0044-compression-belongs-to-the-caller
- 0045-a-console-call-carries-its-reason-on-the-line
- 0046-check-adr-immutable-runs-in-ci-only
- 0047-one-gate-per-kernel-not-one-per-alphabet
- 0048-the-gate-depends-on-the-kernel-and-the-alphabet
- 0049-two-gates-per-kernel-tested-where-the-width-is-known
- 0050-the-sentencepiece-bpe-lineage-stays-a-bpe-model
- benchmark_latest
- decisions
- equivalence
- matplotlib
- migration
- nightly_run
- numpy
- pandas
- performance
- pytorch
- seaborn
- sklearn
- statsmodels