Skip to content

fix(group): a given-name title licenses the bound-given join (#369) - #422

Merged
derek73 merged 5 commits into
masterfrom
fix/369-given-name-title-licenses-bound-join
Aug 22, 2026
Merged

fix(group): a given-name title licenses the bound-given join (#369)#422
derek73 merged 5 commits into
masterfrom
fix/369-given-name-title-licenses-bound-join

Conversation

@derek73

@derek73 derek73 commented Aug 22, 2026

Copy link
Copy Markdown
Owner

Closes #369 — the one within-cycle regression from #367 (Sheik Abu Bakar read given Abu, family Bakar on master where 2.1.0 read given Abu Bakar), fixed by the rule that should have produced that reading all along.

The change

P5's bound-given join (abdul, abu, …) needs a name word to spare for the family, and a title is not a name word, so behind one two words never joined. But sheik is a given-name title — the vocabulary H1 reads as "a given name follows", which is what keeps Sir John a given name with no family. Behind a given-name title the join now uses the post-comma LENIENT reserve.

input before after
Sheik Abu Bakar given Abu, family Bakar given Abu Bakar (restored)
Sheik abdul salam given abdul, family salam given abdul salam, family ''
الشيخ عبد الله given عبد, family الله given عبد الله
Dr. abdul salam unchanged unchanged — a title that addresses by family keeps STRICT
Sir abdul van der Berg unchanged unchanged — the licence is for two words; a particle chain is the family
Sheik abdul Jr Smith unchanged unchanged — a suffix is not a name word either

Four constraints keep it narrow:

  • The title run is keyed through _title_key exactly as post_rules keys H1, so P5 and H1 cannot read one run two ways (mr sir and sir and mrs are not given-name titles to either). Pinned as a parametrized contract over eleven title runs.
  • The piece the join takes must be a single word — not a particle chain (found by the design-docs review) and not a suffix piece (found by the PR review; abdul Jr Smith Berg reads given abdul Jr — P5's join takes a suffix as "the word after" the bound word #421's shape, kept away from titled names).
  • Only STRICT relaxes; the family comma's DISABLED segment never reaches the block and LENIENT is already the floor.
  • absorbs_marker still holds under the lowered reserve.

With the join taking Abu before it can be a lone leading particle, Sheik Abu Bakar no longer reports PARTICLE_OR_GIVEN. That is correct (a bound word read as the bound word is not a fork) and is now stated in P5 as the precedence over P4 where the join fires — Abu Bakar Salim had exercised it silently all along, and bare Abu Bakar keeps P4's reading and its report.

Accepted, not scoped: the join is order-blind, so under FAMILY_FIRST / FAMILY_FIRST_GIVEN_LAST the licensed pair lands in the family with no given name (Sheik abdul salam → family abdul salam), exactly as Sir John reads family John there — H1's exemption never runs under a family-first order, so the two rules still agree. Scoping the licence to the given-first read would need the effective order, which assign settles after group. Recorded in rules.md (family-first rows), decisions.md and the release bullet; two corpus names move under each family-first order, measured by hand (the gate reads the default order).

Verification

  • Suite: 5199 passed, 212 skipped, 10 xfailed (the Sheik abdul salam splits the bound given name that abdul salam ahmed joins #369 xfail goes live); ruff and mypy clean. Every commit is green on its own.
  • Differential gate exits 0 at 1.4.0, 2.0.0 and 2.1.0. Two corpus names move in fields at every baseline — Sheik abdul salam and its Jr spelling from the rules examples; Sheik Abu Bakar is byte-identical to every baseline and differs from 2.0.0/2.1.0 in its report alone. The three old fix(#369) ledger rules classified the regression; they are rewritten to classify the fix (two narrow rules at 2.x — no Latin alternation needed), and the 1.4.0 one is what keeps Sheik abdul salam off the fields-only suffix-routing catch-all.
  • Reviews run on the branch: design-docs-reviewer (four findings), then code-reviewer, pr-test-analyzer and comment-analyzer (three important + a handful of test/comment items). All addressed in commits 3–5; nothing deferred except the abdul Smith V loses the family name — the bound-given join counts an initial-shaped suffix as a name word to spare #401 note below.

Commits

  1. fix(group) — the licence, tests (group + parser), ledgers, release log, AGENTS.md.
  2. docs(design) — rules.md#P5/#H1/#P4, decisions.md#P5, regenerated corpus_rules.jsonl, reach pins.
  3. fix(group) — the licence declines a suffix piece; comment corrections from review (the "no corpus name has the shape" claim was false on this very branch: rules.md examples are corpus names, and the gate witnesses the single-word clause).
  4. test(parser) — the H1/P5 agreement contract, the ambiguity-report assertions, the Arabic-script row.
  5. docs(design) — the family-first Accepted outcome, the suffix/P4 statements and examples, the abdul Smith V loses the family name — the bound-given join counts an initial-shaped suffix as a name word to spare #401 note, ledger wording, reach re-pins.

For the reviewer

🤖 Generated with Claude Code

derek73 and others added 2 commits August 22, 2026 02:37
P5 joins a bound given-name word ('abdul', 'abu') to the word after
it only with a name word to spare for the family, and a title is not
a name word, so behind one two words never joined: 'Sheik abdul
salam' read given 'abdul', family 'salam'. But 'sheik' is a
GIVEN-NAME title -- the vocabulary H1 reads as the assertion that a
given name follows, which is what keeps 'Sir John' a given name with
no family -- so behind one there is no family to spare. The reserve
behind a given-name title is now the post-comma LENIENT one: 'Sheik
abdul salam' reads given 'abdul salam', family '', and 'الشيخ عبد
الله' reads given 'عبد الله'. A title that addresses by family keeps
STRICT ('Dr. abdul salam' is unchanged).

The run is keyed through _title_key over the whole title run exactly
as post_rules keys H1, so the two rules cannot read one run two ways
('mr sir' is not a given-name title to either). The licence lifts the
reserve for two WORDS: the piece the join takes must be a single
word, not a particle chain, which is the family name P2 built --
without that 'Sir abdul van der Berg' lost its surname (found at
review). Only STRICT relaxes; the family comma's DISABLED segment has
no given name to join.

This restores 'Sheik Abu Bakar' to given 'Abu Bakar', the reading
#367 regressed, by the rule that should have produced it: the
bound-given join rather than the particle chain that used to fire
because the title displaced 'abu' out of the leading position. With
the join taking the word, the PARTICLE_OR_GIVEN report that name
carried through 2.1 is gone -- a bound word read as the bound word is
not a fork.

Gate at 1.4.0, 2.0.0 and 2.1.0: 'Sheik abdul salam' is the one corpus
name whose fields move; 'Sheik Abu Bakar' is byte-identical to every
baseline and differs from 2.0.0/2.1.0 in its report alone. The three
fix(#369) ledger rules that classified the regression are rewritten
to classify the fix -- split in two at 2.x so no Latin alternation is
needed -- and the 1.4.0 one is what keeps 'Sheik abdul salam' off the
fields-only suffix-routing catch-all. The #369 xfail in test_parser
goes live.

Closes #369

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
rules.md#P5 gains the clause -- after a given-name title the two
words join and the name has no family; two WORDS, so a particle chain
is not joined; the title run is one key, as H1 reads it -- with
examples for 'Sheik abdul salam', 'Sheik Abu Bakar', and the
boundaries 'Dr. abdul salam' and 'Sir abdul van der Berg', and an
Accepted block for the empty family, the same one H1 records for
'Sir John'. It also states the precedence 'Sheik Abu Bakar' only
exercised: a bound word that is also a particle is read as the bound
word, the join outranking P4's leading-position reading with no fork
reported -- the reading 'Abu Bakar Salim' has always had, never
written down; P4 and P5 now point at each other, as do H1 and P5.

decisions.md#P5 carries the dated entry: the question #369 put, the
signal that decided it, what measured at all three baselines, and the
two things review added (the single-word clause and the P4
precedence). corpus_rules.jsonl regenerated for the five new example
lines; the 1.4.0 suffix-routing reach pin moves 1025 -> 1028 because
its regex reaches three of them, none of which diff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@derek73 derek73 added the bug label Aug 22, 2026
@derek73 derek73 self-assigned this Aug 22, 2026
@derek73 derek73 added this to the v2.2 milestone Aug 22, 2026
@codecov

codecov Bot commented Aug 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.56%. Comparing base (58ab662) to head (ca64ed0).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #422   +/-   ##
=======================================
  Coverage   98.56%   98.56%           
=======================================
  Files          44       44           
  Lines        2993     2997    +4     
=======================================
+ Hits         2950     2954    +4     
  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.

derek73 and others added 3 commits August 22, 2026 02:57
Lowered to LENIENT, the reserve let the bound-given join absorb a
suffix piece behind a given-name title -- 'Sheik abdul Jr Smith'
read given 'abdul Jr', where the plain-title and untitled spellings
keep given 'abdul', middle 'Jr'. That is the shape #421 records for
the post-comma LENIENT path, which the STRICT reserve had kept away
from titled names; the licence now declines a suffix piece on its
own (#421 will make the decline general). Found by PR review.

Also from review, comments only: the "no corpus name has the shape"
claim for 'Sir abdul van der Berg' was false on the same branch --
the rules.md example carries it into the rules corpus, which the
gate reads -- so the comment now says the gate witnesses the clause;
the STRICT test is documented as documentary (DISABLED never reaches
the block and LENIENT is the floor); the H1 key agreement notes that
post_rules' run also takes H2's unlisted abbreviations, which no
given-name title key can contain; and the module docstring's
doubled Policy.extra_suffix_delimiters sentence is folded into one.

Group tests: the suffix decline (RED first), a conjunction-joined
title run keyed whole ('sir and mrs' is not 'sir'), and the declined
lone marker still declined under the lowered reserve.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three contracts the branch stated in prose and nothing asserted, from
PR review. The H1/P5 agreement is the licence's one invariant --
P5 lifts the reserve behind a title run exactly when H1 keeps the
one word after it a given name -- and is now a parametrized test
over eleven runs (plain, given-name, mixed, conjunction-joined,
Arabic): "no family" must agree for '{title} John' and '{title}
abdul rahman'. 'Sheik Abu Bakar' asserts its empty ambiguity tuple
beside the given name, with 'Abu Bakar Salim' (no report) and 'Abu
Bakar' (P4's report stands where the reserve blocks the join) as the
two sides of the precedence rules.md#P5 now states. And the Arabic
table gains 'الشيخ عبد الله' -> given 'عبد الله', family '' -- thirteen
of the given-name titles are that script's, and no test or corpus
row had exercised the licence on one.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e witnesses

The join is order-blind, so under FAMILY_FIRST and
FAMILY_FIRST_GIVEN_LAST the licensed pair lands in the family with
no given name: 'Sheik abdul salam' reads family 'abdul salam' (was
family 'abdul', given 'salam'), as 'Sir John' reads family 'John'
there -- H1's exemption never runs under a family-first order, so
the two rules still agree. Recorded as Accepted in rules.md#P5 with
family-first example rows, in the decisions entry, and in the
release-log bullet, which now scopes its orders as its siblings do;
two corpus names move under each family-first order, measured by
hand since the gate reads the default order. Accepted rather than
scoped to the given-first read because the effective order is
settled in assign, after group. Found by PR review.

rules.md#P5 also states that the licence takes a name WORD (neither a
particle chain nor a suffix), qualifies the P4 precedence to where
the join fires, and gains examples for the suffix standing ('Sheik
abdul salam Jr'), the suffix declined ('Sheik abdul Jr Smith') and
P4's reading standing ('Abu Bakar'). The decisions entry corrects
its "no corpus name has either shape" -- 'Sir abdul van der Berg' is
a rules.md example and so in the rules corpus -- and records the
#401 widening ('Sir abdul V' reads given 'abdul V': the reserve's
initial veto, reachable behind a given-name title now). The 1.4.0
ledger rule says again why it exists (the suffix-routing catch-all
would otherwise take the name), and the three join-rule comments
name the Jr example. corpus_rules.jsonl regenerated (169 names);
the join rule's reach pin is 3 names and the 1.4.0 catch-all's 1030.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@derek73
derek73 merged commit 34d9a4d into master Aug 22, 2026
11 checks passed
@derek73
derek73 deleted the fix/369-given-name-title-licenses-bound-join branch August 22, 2026 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sheik abdul salam splits the bound given name that abdul salam ahmed joins

1 participant