Skip to content

Rebuild familiar forms from reviewed ORCID pairs, add opt-in alternate-spelling, and fold keyboard spellings - #1379

Open
derek73 wants to merge 28 commits into
masterfrom
feat/familiar-forms-cc0
Open

derek73 wants to merge 28 commits into
masterfrom
feat/familiar-forms-cc0

Conversation

@derek73

@derek73 derek73 commented Nov 13, 2026 •

Copy link
Copy Markdown
Owner

Rebuilds the familiar forms #1372 dropped from pairs found in CC0 data and reviewed, adds an opt-in outcome for a name spelled two ways by choice, and folds the spellings a keyboard forces into the default.

What changes for a caller

Outcome Default? Example
folded, widened yes Łukasz / Lukasz, Pınar / Pinar, Müller / Mueller, Ødegård / Odegaard, Srđan / Srdjan, in every role, from either side
alternate-spelling, new no, opt-in Yuliya / Iuliia, Aleksey / Alexey, Olga / Olha, Saeed / Saeid: 429 pairs
familiar-form, rebuilt no, opt-in now many languages: Kasia / Katarzyna, Kostas / Konstantinos, Seun / Oluwaseun: 2,848 pairs, the nicknames list's plus 668 from the review

A chosen spelling is not default: people sometimes spell a name differently on purpose, to be told apart. Only a spelling no one chooses, which a keyboard or an encoding forces, is folded by default.

Keys change for names holding ae, oe, ue, aa or dj (decided, as its cost is modest; matching is new in 3.1, so no caller has stored a key). A key now writes those digraphs as their first letter (Doe keys do), so every spelling of Müller cuts one key and a name's keys don't grow 2^k with its forms. Measured under the default setting, master against this PR:

Population Candidate or key pairs Of which the collapse Largest group Mean group
match_diff's 32,017 names (distinct candidate pairs) +0.04% +0.01% unchanged (868) 2.054 → 2.078
orcid-researchers, 1.87M names (key pairs) +0.60% +0.43% unchanged (1,095) 1.726 → 1.736
psc-individuals, 1.03M names (key pairs) +0.14% +0.14% unchanged (856) 2.045 → 2.050
  • Largest growth: the folds' jorgensen;m, 5 → 38 (Jørgensen / Joergensen / Jorgensen, which the folds now match). The collapse's own merges are about 2× at most: sad;* (Saad / Saeed) and xu;y (Xue / Xu).
  • Doe and Do: do;* grows from 363 to 412 names in orcid (largest 112 → 118) and from 43 to 101 in psc.
  • Keys per name: unchanged from master (at most 18 on one name). One key per spelling form would give up to 76.

How the pairs were found and reviewed

  • tools/vocab/familiar_candidates.py finds a pair where one ORCID holder (public data file, CC0) wrote a one-word given-name box and, before the same family name, a different word in a published name (given = Katarzyna, credit = Kasia Nowak). It reads no compiled list of familiar forms except the nicknames list and its refusals, to skip what was already reviewed (decisions/shipped-data-licences, FACTS WE MEASURE). The nicknames list's 165 pairs it had refused as spellings were reviewed again.
  • Review: two independent review agents read each of the 1,633 candidates under one written rubric, the second on another model (Sonnet 5.5). They agreed on 1,495 (91.5%). A pair ships where both agree, or where the maintainer decided a split. Every verdict is in tools/vocab/familiar_reviewed.tsv, with no family names.
  • Routing:
    • folded by default: 66 spellings a keyboard forces, which ship no reading;
    • alternate-spelling: 429 other spellings;
    • familiar-form: 668 pairs;
    • recorded only: translations (235), abbreviations (7) and different names (116);
    • refused: 30.

Measured (tools/differential/match_diff.py, 31,247 pairs × 22 settings)

Change Default verdicts Opt-in verdicts Key guarantee
the opt-in spellings and familiar forms (master → folds off) none move 157 pairs become consistent holds
fold (a), keyboard letters 43 pairs become consistent holds
fold (b), transcriptions 200 pairs become consistent holds
both folds 248 pairs become consistent holds

No fold makes any verdict inconsistent. Two verdicts go from consistent to inconsistent, both from a fix to how a middle name's words combine: an accepted weaker outcome no longer hides a stronger one the caller refuses. They are John Liz Jean Smith / John Elizabeth Jean-Paul Smith under +hyphenated-part alone, and an accented middle name under -folded. The parse snapshot is byte-identical: no parse moves.

Design

  • A new matching-only kind, spelling = { spelling_of = [...] }, compiling into ALTERNATE_SPELLINGS alone, not a given reading's same_as, which means "written short" and moves parses (measured in the decisions entry).
  • Pairs are read either way round and never chained, as familiar forms are.
  • A given name needing both an alternate spelling and a familiar form is accepted only where the caller accepts both.

The records are in decisions/name-matching: "2026-11-12 A KEYBOARD'S SPELLING IS FOLDED" and "2026-11-12 ALTERNATE SPELLINGS ARE OPT-IN".

Open, not built: a translation outcome, cross-script matching, phonetic matching (Gerry / Jerry), routing abbreviations (Md, which moves parses), a caller's same_as reached from other forms of the word, and Wikidata for the languages ORCID covers thinly (German, Russian, Ukrainian, Belarusian, Hungarian, Romanian, Bulgarian, Croatian, Serbian, Albanian; figures in the entry).

Tests and reviews

  • Checks: the full suite passes (46,922), as do ruff, mypy, the Sphinx doctests and the README doctest.
  • Controls: every new guard has a negative control that fails with its code removed.
  • Reviews:
    • a design-docs review and a code review of the change;
    • a review of each of the three fix commits;
    • every finding fixed, or recorded as Open where noted.

🤖 Generated with Claude Code

…RCID for review

A familiar form is rebuilt from pairs the project finds in data it may
use, never from a compiled list (decisions/shipped-data-licences,
2026-11-12 #1370 FACTS WE MEASURE): one ORCID holder (CC0) writing a
single given name in the box and another word before the same family
name in a credit or other name. The tool writes candidates and their
counts to the cache, with GND's attestation on request and a seeded,
stratified pilot draw; it reads no list of familiar forms but the
nicknames list and its refusals, to leave out what was reviewed.
Nothing is written into the vocabulary yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73 derek73 added tooling vocabulary Fixed by a word-list entry: per-word vocabulary and language packs matching Name matching: Parser.matching(), check() and keys() labels Nov 13, 2026
@derek73 derek73 self-assigned this Nov 13, 2026
test_the_check_refuses_every_read_4i_a_moved counts every read of a
Lexicon's sets the check would refuse with the move undone; the new
tool reads the default's titles, 20 -> 21.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73 derek73 added this to the 3.1 milestone Nov 13, 2026
… review

The review now keeps every category it assigns: a spelling of one name
ships as a listed spelling, a familiar form as a familiar reading, and a
transliteration or translation is recorded. So a pair in two scripts is
kept and shaped as one rather than dropped, each row says its source and
shape, and the nicknames list's pairs refused as spellings, read before
only as familiar forms, come back as candidates of their own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73 derek73 changed the title Draw familiar forms from ORCID for review, to rebuild other languages' pairs Draw familiar forms and spellings from ORCID for review, to rebuild other languages' pairs Nov 13, 2026
derek73 and others added 21 commits November 12, 2026 23:13
Resolve the layering control's count: master's order_names.py reads
four, 20 -> 24, and familiar_candidates.py one, 24 -> 25.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…f its own

A spelling is a matching-only kind, spelling = { spelling_of = [...] },
compiling into SAME_AS's given group alone, so the name match reads it
as listed-spelling and no parse reads it: unlike a given reading's
same_as, it is no name written short (GIVEN_NAME_ABBREVIATIONS) and
gives the word no name reading that could gate it.

tools/vocab/familiar_reviewed.tsv records the review of 1,633 candidate
pairs (ORCID at 3+ holders and the nicknames list's refused spellings),
each read by two independent readers; familiar.py writes the 665 pairs
both called familiar forms and the 460 both called spellings, less five
held, in the file of each language their holders' countries write, the
nicknames list's beside them in en.toml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A given name one word of which is an alternate spelling and another a
familiar form reads familiar-form only where both outcomes are
accepted, and otherwise the one refused; and the middle role's words
combine so an accepted weaker outcome never hides a stronger one the
caller refuses, which also closes the older case of hyphenated-part
hiding familiar-form. The review of #1379 found both, the first
breaking the key guarantee.

Also: the refusals of a matching-only add offer code that runs; the
spelling kind's tests stand beside the familiar kind's; match_diff's
tolerance of an outcome a base does not know has a control.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…in the name match

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rrected

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review of the fold rules found three places where the
transcription reached one side and not the other: a word or text
mixing the two writings (Ødegård / Odegaard), a hyphenated part, and the
vocabulary's own listed spellings, familiar forms and alternate
spellings, which a caller's entry holding the letter missed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review of 492e61d found asking a familiar form or an alternate
spelling from both sides read one side's fold against the other's
transcription and missed two transcriptions (Guenni / Guenther), and a
name's keys growing 2^k in its transcribable letters (530 for one
Danish name). The pairs are indexed under every form of both names,
read one-sided and symmetric by construction again, and a key writes
the transcription digraphs as their first letter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
derek73 and others added 2 commits November 13, 2026 01:09
The review of 87b1d5c found a caller's pair written with U+2010 read
one way only, the index keyed by that hyphen and the match reading the
hyphen-minus. The hyphens move below the pipeline into _lexicon, whose
forms write them as the hyphen-minus; and the keys' prose says a key
writes the transcription digraphs as their first letter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
he.toml and the reading index regenerated by familiar.py and build.py
over master's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73 derek73 changed the title Draw familiar forms and spellings from ORCID for review, to rebuild other languages' pairs Rebuild familiar forms from reviewed ORCID pairs, add opt-in alternate-spelling, and fold keyboard spellings Nov 13, 2026
@derek73
derek73 marked this pull request as ready for review November 13, 2026 09:11
derek73 and others added 2 commits November 13, 2026 01:18
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

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

Labels

matching Name matching: Parser.matching(), check() and keys() tooling vocabulary Fixed by a word-list entry: per-word vocabulary and language packs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant