Skip to content

Add the Irish particles Ó, Ní, Ua and the Malay binti/binte - #607

Merged
derek73 merged 3 commits into
masterfrom
fix/issue-604-irish-malay-particles
Oct 4, 2026
Merged

derek73 merged 3 commits into
masterfrom
fix/issue-604-irish-malay-particles

Conversation

@derek73

@derek73 derek73 commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Closes #604.

What changes

  • New particles. ó and ní join the never-given particles; ua, binti and binte join the ambiguous half.
    • HumanName("Liam Ó Murchú") gives last Ó Murchú, where 1.4.0 through 2.3.0 gave middle Ó. Sinéad Ní Mhurchú, Seán Ua Buachalla and Ina binti Navalamar move the same way.
    • Ó Murchú alone is all surname; every release gave first Ó.
    • A leading Ua Buachalla keeps given Ua and reports particle-or-given. ua is ambiguous because the search for given-name use was thin, and C-i defaults to ambiguous under uncertainty. The marking differs from never-given in three places, all recorded: the opening, after a family comma, and P6's trailing report.
  • New rule P7. A one-letter word written with an ASCII period is an initial, never a particle.
    • Juan Ó. Pérez keeps middle Ó., as do J. Ó. Pérez and Pérez, Juan Ó..
    • The bare Juan Ó Pérez gives last Ó Pérez (the accepted cost).
    • One helper, _lexicon._spells_an_initial, is asked after the membership hit at every site that reads the particle vocabulary directly: classify, _vocab.surname_unit_tags, _render._cap_word and the facade's _is_particle. Segment's credential-run walk is not a site: an initial ends that walk before the question comes up, so a veto there was measured to change nothing.
  • Case repair (rules.md#R4). A capitalization_exceptions mask now outranks the particle lowercase, and ó/ní/ua ship masks.
    • SEÁN Ó MURCHÚ repairs to Seán Ó Murchú. Without the masks it would regress to Seán ó Murchú.
    • This is deliberate for caller maps too. With 'van': 'Van' in the map, ludwig van beethoven repairs to Ludwig Van Beethoven, where 1.4.0 through 2.3.0 kept van. The differential gate cannot see capitalized(), so the release log says this explicitly.
    • binti repairs to lowercase, where 2.3.0 gave Binti.

Accepted, recorded in decisions.md#P7

A caller-configured one-character particle in Han, Hangul or kana, written with a period, is vetoed even though is_initial says those scripts have no initials. Doing this properly needs _policy's script table, which _lexicon, _render and the facade may not import. No shipped particle is affected.

Guards

  • A two-input invariant in tests/v2/test_properties.py: a name holding Ó. reads exactly as the same name holding Q., in the parse fields, reports, initials(), capitalized() and the facade's views. The grid is 537 texts. The invariant and its per-site control (next item) together take about 3.3s, the Q. side being walked once per lexicon.
  • _P7_SITE_EFFECT records, per site, how many grid texts break with that site's veto removed.
  • test_surname_unit_tags_agree_with_classify's sweep now holds the period-written one-letter particle, with a negative control for the _vocab veto.
  • Case rows in tests/v2/cases.py for the P7 contrast and the leading Ua.
  • Two mask tests in tests/v2/test_render.py: the shipped particle masks with a de control, and a caller particle mask.

Docs

  • rules.md: P7, and the R4 amendment with two examples.
  • decisions.md: P7, a vocabulary-collisions application, Excluded entries (nic, bare o, bt/bte), and an R4 entry.
  • customize.rst: a doctest.
  • release_log.rst: a bullet.

Verification

  • Suite: 11,249 passed. Ruff, mypy and the Sphinx doctests are clean.
  • Differential gate exits 0 at 1.4.0, 2.0.0, 2.1.0, 2.2.0 and 2.3.0. One fix(#604) ledger rule covers the three movers. The radar entries are identical to master's.
  • Reviews:
    • A design-docs review and a code review ran on the first draft; all their findings were applied.
    • A second review of that fix round found three more doc corrections, applied in the second commit.
    • A /simplify pass tightened the tests in a third commit (shared grid walk, Lexicon | merge, the agreement-sweep gap above). Its one skipped suggestion: swapping the P7 views for the broader _signature helper, which would make the comparison stricter rather than tidier.

🤖 Generated with Claude Code

derek73 and others added 2 commits October 4, 2026 02:07
ó and ní join the never-given particles; ua, binti and binte the
ambiguous half (decisions.md#vocabulary-collisions), so the particle
opens the surname behind it where every release read it as a middle
name ("Liam Ó Murchú" -> family "Ó Murchú").

New rule P7: a one-letter word written with an ASCII period is an
initial, never a particle, so "Juan Ó. Pérez" keeps middle "Ó.".
One helper, _lexicon._spells_an_initial, asked after the membership
hit at every site that reads the particle vocabulary directly
(classify, _vocab.surname_unit_tags, _render._cap_word, the facade's
_is_particle). Guarded by a two-input invariant (Ó. reads as Q.) with
a per-site negative control.

Case repair: a capitalization_exceptions mask now outranks the
particle lowercase (rules.md#R4), and ó/ní/ua ship masks, so
"SEÁN Ó MURCHÚ" repairs to "Seán Ó Murchú". Deliberate for caller
maps too: a 'van' -> 'Van' entry now wins where 1.4.0-2.3.0 kept
"van" (release log says so; the gate cannot see capitalized()).

Ledger rule fix(#604) in all five ledgers; gate exits 0 at every
baseline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- decisions.md#P7: the connective period line is stated in R4's hyphen
  clause, so 'stated in no rule' was self-contradictory
- decisions.md#P7: the segment null's recipe patched a call that no
  longer exists; say how it was measured and how to re-check it
- decisions.md#R4 and capitalization.py: the dotted reach is n.í. as
  well as u.a.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73 derek73 added this to the 2.4 milestone Oct 4, 2026
@derek73 derek73 self-assigned this Oct 4, 2026
@codecov

codecov Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.98%. Comparing base (aa401d8) to head (0256a80).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #607   +/-   ##
=======================================
  Coverage   98.98%   98.98%           
=======================================
  Files          45       45           
  Lines        4238     4241    +3     
=======================================
+ Hits         4195     4198    +3     
  Misses         43       43           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- the P7 invariant's 'Q.' side is walked once per lexicon and shared,
  and the site control no longer re-walks the default-lexicon baseline
  the invariant already holds: about 7.1s -> 3.3s for the five tests
- the no-mask lexicon drops every particle mask, derived rather than
  listed
- the caller-mask test merges with Lexicon | rather than a hand-built
  tuple
- the surname-unit agreement sweep (test_classify) now holds the
  period-written one-letter particle, with a negative control: it was
  blind to the _vocab veto, held only by the P7 grid

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73
derek73 merged commit aab5fa9 into master Oct 4, 2026
11 checks passed
@derek73
derek73 deleted the fix/issue-604-irish-malay-particles branch October 4, 2026 09:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Liam Ó Murchú reads Ó as a middle initial: add the Irish particles Ó, Ní, Ua (and Malay binti)

1 participant