Skip to content

Read Wing as a given name outside a title phrase, after a comma too (#752, phase 2j) - #896

Merged
derek73 merged 1 commit into
masterfrom
feat/752-phase2j-wing
Oct 26, 2026
Merged

derek73 merged 1 commit into
masterfrom
feat/752-phase2j-wing

Conversation

@derek73

@derek73 derek73 commented Oct 26, 2026

Copy link
Copy Markdown
Owner

The first title batch of phase 2j (#752): wing gains a dated given reading, so it is a title only inside a title phrase wherever it stands.

What changes

Phase 2i's decision 10 already reads a lone Wing at the head of a name as the given name (Wing Lau, Mr Wing Lau), so what was left for wing is the two places decision 10 reads a modifier as listed: after a comma, and ending the name. A word that is both a modifier and a possible given name is read by the head's modifier test in every part (a title only with a head title after it in its run, of after it, or in the object of of or the):

input 1.4.0 – 2.6.0 now
Lau, Wing Kai title Wing, given Kai given Wing, middle Kai
Lau, Wing title Wing given Wing
John Smith Wing. title Wing. (2.3.0–2.6.0; 1.4.0–2.2.0 family) family Wing.
Lau, Wing Commander title Wing Commander unchanged
Wing Commander Lau title Wing Commander unchanged

Alone after a comma wing reads as dean has since phase 2i, including the cost decision 10 measured for role words: John Smith, Wing reverses to given Wing, family John Smith, as John Smith, Dean does. Accepted because the listing form is what writes the word there: of FEC's 22 names writing WING after a comma, the 14 opening the part with it are all FAMILY, WING …, and ctgov writes none. Elsewhere the two follow different tests (a twin grid read 1,854 of 8,820 texts differently), so wing is not a template for the contested titles. No listed phrase holds wing, so nothing is reported (Wing Lau stays silent).

Pinned as rows, all as master read them, none written by a corpus name:

  • LAU, WING MR keeps title WING MR (the modifier test takes a salutation as its head), where LAU, DEAN MR gives given DEAN.
  • Accepted in rules/H9: The Hon. Wing Lau keeps title The Hon. Wing (object of the), and John Smith Wing. Jr. keeps title Wing. (H2's shape reads the dotted suffix as a head; John Smith Wing. MD gives family Wing.).

Measured

Against master 12384fae, py3.11, every local corpus with --base; counts and token shapes only.

  • fec-individuals: 14 moved, all fixed: AA, WING 7, AA, WING AA… 6, AA, WING A. MR. 1.
  • Committed corpora: 1 move, H9's former Accepted example Lau, Wing, plus 6 new rule examples.
  • No moves: CLDR/GND agreement, PSC (1,039,174 scored), ctgov-officials and tse-donors. PSC scores spoken order, where 2i already took wing's 25 fixes.
  • Spelling pairs: jrc-names 0 now alike / 0 now apart of 218,822 persons; nepal-candidates 0 / 0 of 126,981 pairs. No spelling writes Wing after a comma.

Docs

  • rules/H9:
    • The modifier bullet now covers a modifier that may be a given name.
    • New Precedence bullet: the modifier test, not a contested word's style partner, decides a word in both sets (Hon. Wing Lau keeps given Wing).
    • The Accepted example moves to Hudson, Rock, and two Accepted costs are added (above).
    • Because carries the reason.
    • Signal line widened from "the leading run" to "its run of titles".
    • The rule budget is re-recorded: H9 grows (Then 245 → 265 words, Accepted 5 → 6 bullets, 162 → 211 words): the new clause and its costs.
  • decisions/H9: dated entry with SUPERSEDES for the old Lau, Wing cost, and the Standing line amended.
  • decisions/vocabulary-model: Standing line and a log pointer.
  • Release log: the existing "lone title qualifier" bullet gains the Wing exception.
  • Stale prose fixed:
    • vocab README's modifier kind;
    • the RFC's decision-10 line;
    • the title_readings, Lexicon.title_modifiers and config.titles.TITLE_MODIFIERS docstrings, which said every modifier is in TITLES.
  • Counts recorded on the word: SSA 188, Wikidata 17 given; Census 12,614, Wikidata 218 family; nam_dict band 1 in China.

Checks

uv run pytest (26,335 passed), -n0 -m serial, --python 3.15, mypy, ruff, sphinx-build -b doctest. The design-docs review (two rounds) ran a 26,460-parse shape grid; its findings (undersold reach, the reversal, the both-sets precedence, stale prose, then an overclaimed "reads as dean" and the dotted-suffix spelling) are fixed in this commit.

Refs #752, #853

🤖 Generated with Claude Code

…752, phase 2j)

The first title batch of phase 2j. `wing` gains a dated given reading,
which puts it in TITLES_AMBIGUOUS beside TITLE_MODIFIERS. Phase 2i's
decision 10 already read a lone `Wing` at the head of the name as the
given name; a word in both sets is read by the head's modifier test in
every part, so the reading reaches the two sites decision 10 left as
listed. After a comma `Lau, Wing Kai` reads given 'Wing', middle 'Kai',
where 1.4.0 through 2.6.0 read title 'Wing'; ending the name
`John Smith Wing.` reads family 'Wing.', as 1.4.0 through 2.2.0 did,
where 2.3.0 through 2.6.0 read a title. `Lau, Wing Commander` and
`Wing Commander Lau` keep the title; `John Smith, Wing` reverses as
`John Smith, Dean` does.

rules/H9 amended (a Precedence bullet for a word in both sets, Accepted
costs `The Hon. Wing Lau` and `John Smith Wing. Jr.`, its former example
moved to `Hudson, Rock`, its Signal line widened to the run);
decisions/H9 and decisions/vocabulary-model carry the dated entry and
the measurement (FEC 14 fixed, committed 1, PSC/ctgov/tse/pairs 0).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73 derek73 added enhancement design vocabulary Per-word vocabulary model and language packs labels Oct 26, 2026
@derek73 derek73 self-assigned this Oct 26, 2026
@derek73 derek73 added this to the 2.7 milestone Oct 26, 2026
@derek73
derek73 merged commit 32049ad into master Oct 26, 2026
12 checks passed
@derek73
derek73 deleted the feat/752-phase2j-wing branch October 26, 2026 21:35
derek73 added a commit that referenced this pull request Oct 27, 2026
…nce and usage in one run

Phase 2j (#896 through #912) rewrote about ten probe scripts each batch:
a shape grid, corpus incidence counts, a usage lookup. #913 lists about
22 more words for rules/H9 (the title phrase), so the probes become a
committed tool.

- grid: the word in 25 shapes (a head, behind a title or a style,
  after a family comma, after a full name and a comma, past a second
  comma, trailing with a period, the article epithet, its own title
  phrase), each in three cases and under all three name orders; with
  --base only the rows the trees read differently.
- corpora: in every fetched local corpus, the names opening with the
  word or opening the part after a comma with it, counted by reading
  (title, given, other). Counts only: no name is printed.
- usage: name_usage.py --no-wikidata --json's row.
- --rank orders words by the corpus names that open with the word and
  read it as the title, the triage #913 asks for, with no head change.

Each tree is read in a child process of its own, which refuses a
nameparser imported from outside its tree (snapshot.check_source).
snapshot.read's spawn pool becomes snapshot.parallel, shared by the
child and, in the next commits, the agreement score and pairs views.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
derek73 added a commit that referenced this pull request Oct 27, 2026
…nce and usage in one run

Phase 2j (#896 through #912) rewrote about ten probe scripts each batch:
a shape grid, corpus incidence counts, a usage lookup. #913 lists about
22 more words for rules/H9 (the title phrase), so the probes become a
committed tool.

- grid: the word in 25 shapes (a head, behind a title or a style,
  after a family comma, after a full name and a comma, past a second
  comma, trailing with a period, the article epithet, its own title
  phrase), each in three cases and under all three name orders, folded
  where cases or orders read alike; with --base only what moved.
  For sheikh against its pre-#912 base that is 120 lines.
- corpora: in every fetched local corpus, the names opening with the
  word or opening the part after a comma with it, counted by reading
  (title, given, other). In psc-individuals, the names opening with the
  word are also counted by the box the filer typed it into. Counts
  only: no name is printed. A corpus not fetched is named, and a
  damaged one ends the run.
- usage: name_usage.py --no-wikidata --json's rows.
- --rank, the triage #913 asks for, with no head change: the title
  readings at both positions, beside the PSC title-box and forename-box
  filings, ordered by the forename share. A title-box filing is a real
  title, which the move would cost. A forename-box filing is a given
  name the title reading takes, which the move gives back. On
  2026-10-27: sir 277 / 8, sheikh 13 / 32, the 13 being the agreement
  records #912 moved away from agreeing.

Each tree is read in a child process of its own, the two run at once,
and each refuses a nameparser imported from outside its tree
(snapshot.check_source). snapshot.read's spawn pool becomes
snapshot.parallel, shared by the child and, in the next commits, the
agreement score and pairs views.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
derek73 added a commit that referenced this pull request Oct 27, 2026
…nce and usage in one run

Phase 2j (#896 through #912) rewrote about ten probe scripts each batch:
a shape grid, corpus incidence counts, a usage lookup. #913 lists about
22 more words for rules/H9 (the title phrase), so the probes become a
committed tool.

- grid: the word in 25 shapes (a head, behind a title or a style,
  after a family comma, after a full name and a comma, past a second
  comma, trailing with a period, the article epithet, its own title
  phrase), each in three cases and under all three name orders, folded
  where cases or orders read alike; with --base only what moved.
  For sheikh against its pre-#912 base that is 120 lines.
- corpora: in every fetched local corpus, the names opening with the
  word or opening the part after a comma with it, counted by reading
  (title, given, other). In psc-individuals, the names opening with the
  word are also counted by the box the filer typed it into. Counts
  only: no name is printed. A corpus not fetched is named, and a
  damaged one ends the run.
- usage: name_usage.py --no-wikidata --json's rows.
- --rank, the triage #913 asks for, with no head change: the title
  readings at both positions, beside the PSC forename-box and title-box
  filings and the forename box over the two (28/34), ordered by the
  forename box's count, since a count cannot be rebuilt from a share. A title-box filing is a real
  title, which the move would cost. A forename-box filing is a given
  name the title reading takes, which the move gives back. On
  2026-10-27: sir 277 / 8, sheikh 13 / 32, the 13 being the agreement
  records #912 moved away from agreeing.

Each tree is read in a child process of its own, the two run at once,
and each refuses a nameparser imported from outside its tree
(snapshot.check_source). snapshot.read's spawn pool becomes
snapshot.parallel, shared by the child and, in the next commits, the
agreement score and pairs views.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
derek73 added a commit that referenced this pull request Oct 27, 2026
…_report.py, --jobs, alike, measure.py) (#917)

* Add tools/vocab/word_report.py: a word's H9 shape grid, corpus incidence and usage in one run

Phase 2j (#896 through #912) rewrote about ten probe scripts each batch:
a shape grid, corpus incidence counts, a usage lookup. #913 lists about
22 more words for rules/H9 (the title phrase), so the probes become a
committed tool.

- grid: the word in 25 shapes (a head, behind a title or a style,
  after a family comma, after a full name and a comma, past a second
  comma, trailing with a period, the article epithet, its own title
  phrase), each in three cases and under all three name orders, folded
  where cases or orders read alike; with --base only what moved.
  For sheikh against its pre-#912 base that is 120 lines.
- corpora: in every fetched local corpus, the names opening with the
  word or opening the part after a comma with it, counted by reading
  (title, given, other). In psc-individuals, the names opening with the
  word are also counted by the box the filer typed it into. Counts
  only: no name is printed. A corpus not fetched is named, and a
  damaged one ends the run.
- usage: name_usage.py --no-wikidata --json's rows.
- --rank, the triage #913 asks for, with no head change: the title
  readings at both positions, beside the PSC forename-box and title-box
  filings and the forename box over the two (28/34), ordered by the
  forename box's count, since a count cannot be rebuilt from a share. A title-box filing is a real
  title, which the move would cost. A forename-box filing is a given
  name the title reading takes, which the move gives back. On
  2026-10-27: sir 277 / 8, sheikh 13 / 32, the 13 being the agreement
  records #912 moved away from agreeing.

Each tree is read in a child process of its own, the two run at once,
and each refuses a nameparser imported from outside its tree
(snapshot.check_source). snapshot.read's spawn pool becomes
snapshot.parallel, shared by the child and, in the next commits, the
agreement score and pairs views.

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

* Score and read the spelling views in workers, and keep a base for the alike view

local_agreement.py's score and local_corpora.py's pairs --agreement and
groups views parsed every name in one process. They now read through
snapshot.parallel with --jobs (default every CPU), and its workers abort
the run where one imported another nameparser. Measured 2026-10-27 on
12 CPUs, each output byte-identical before and after: psc-individuals
88.9s -> 15.4s, groups jrc-names 55.6s -> 11.8s, pairs tse-donors
--agreement 52.1s -> 15.8s.

New `alike SOURCE --base <checkout>` view: whether each person's
spellings read alike (jrc-names persons, nepal-candidates romanized and
Devanagari pairs, tse-donors filed and registry pairs), and how many now
read alike and now apart against the base. That replaces phase 2j's
scratch pairs script, which parsed the base again for every commit. The
base's flags are kept under alike/, keyed by the fetch, the base
package's digest, the interpreter and the view's code (alike_fingerprint,
its hand-kept list guarded like _FOLD_CODE). They are published only
once whole and once the digest, taken again, is unchanged. A key names
no one.

plant_corpus now carries the real source's corpus_keys, so a nepal
corpus planted for a --base child passes the child's key check.

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

* Add tools/differential/measure.py: every corpus check of a change, in sequence, with one summary

Each phase 2j batch spent about ten minutes on a hand-written
measure.sh. measure.py --base <checkout> runs the same steps one at a
time, each but cldr_agreement.py parallel inside itself:
- the committed snapshot and cldr_agreement.py, against the records
  committed on the branch;
- snapshot.py --local --base for every fetched corpus;
- local_agreement.py psc-individuals --base;
- local_corpora.py alike --base for every fetched source that pairs
  spellings.
The summary labels each step with what it compared against, names the
local corpora that are not fetched, and fails a run in which no step
read --base.

Each step's whole output goes to a file under --out (by default the
tools' cache, since a local snapshot lists moves by name). summary.txt
keeps each step's unindented lines: the first few, the last ones (where
the verdicts are) and any "not measured" line. It never keeps the
indented ones, where the tools list names. Output is read as bytes and
cut at "\n" only, and snapshot.grouped escapes a line break inside a
name, so no part of a name reaches the left edge.

Every tool refuses with SystemExit("message"), which exits 1 like a
move, so each step runs through measure's --step wrapper. The wrapper
turns a message exit or an uncaught exception into exit 2, and prints a
crash's traceback indented below a line naming only its type.

On 2026-10-27, against a base whose package differed only in a README,
it ran 14 steps in 368s on 12 CPUs, each base recorded for the first
time. AGENTS.md's "Adding a word to the vocabulary" and the vocabulary
README point at word_report.py and measure.py.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

design enhancement vocabulary Per-word vocabulary model and language packs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant