Skip to content

Read a bracketed member settled by its writing as the suffix (#752, phase 2l) - #899

Merged
derek73 merged 13 commits into
masterfrom
claude/phase2l-bracket-escape-24a78d
Oct 27, 2026
Merged

derek73 merged 13 commits into
masterfrom
claude/phase2l-bracket-escape-24a78d

Conversation

@derek73

@derek73 derek73 commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Phase 2l of #752. Closes #810.

What changes

A bracketed or quoted clause is now read as the suffix, not a nickname, in one pass when all three hold:

  • it is one word from the ambiguous credential class;
  • it stands after the name, behind a name word, with no name word after it;
  • its spelling settles that it is a credential.

Two spellings settle it:

  • A period inside the word. This is S3's evidence and holds in any case: John Smith (M.A) and JOHN SMITH (M.A) give suffix M.A.
  • Capitals in a name written in mixed case. This is S6's evidence (the case signal at the suffix slot): John Smith (MA), Smith, John (MA) and Andrew Perkins (JD) give a suffix. The case is checked against the name's own words, as 2g's settled_by_case checks it.

These keep the nickname and report suffix-or-nickname:

  • Title case: John Smith (Ed) and John Smith (Ma) lean to the name.
  • A name in one case: JOHN SMITH (MA) and john smith (MA) settle nothing.
  • A name word after the clause: Jeffrey (JD) Bricken, Jean 'JD' Smith, Jean (M.A) Smith, Smith (MA), John and John Smith (MA) Ma.
  • No name word at all: Dr. (MA) and (M.A).

A suffix, a title or a maiden clause after the bracket does not count as a name word. So John Smith (MA) Ph. D., John Smith (MA) Dr. and John Smith (MA) née Jones settle.

Releases:

  • John Smith (MA) and (M.A): 1.4.0 read a suffix, and 2.0.0 through 2.6.0 read a nickname.
  • Andrew Perkins (JD): a nickname from 1.4.0 through 2.6.0.

How it works

  • The decision. post_rules decides first, in its single pass, once every word's role is known. A settled clause becomes the suffix directly. It is not unwrapped and read bare, because since Read a surname written as two dotted initials as a name, not a credential (#864) #872 a bare M.A reads as paired initials (John Smith M.A gives family M.A).
  • The report. The suffix-or-nickname report moved there from classify, so it is raised where the fork is decided. A dotted member left a nickname is now reported too.
  • Cost against master (1353913), in frames: Smith, John and John Smith are unchanged. John Smith (MA) goes 214 → 210, and a name with a clause it does not settle pays 2 to 5.

Accepted (rules/S13). In one pass the rest of the name is read as if the clause were a nickname. Where that differs from the clause's twin, a bracketed unambiguous credential like (PhD) in the same place, the difference is an accepted cost:

  • A lone name word: it stays N3's family name. Jack (MA) gives family Jack, while Jack (PhD) gives given Jack, reported.
  • A maiden clause after the member: it stays the maiden name, where the twin's credential run takes it.
  • The case is asked once: JOHN SMITH (m.a) (MA) leaves MA a nickname, where the twin settles both clauses.
  • A part past a second comma: it is weighed without the member. Smith, John, X.Y.Z. (MA) reports nothing, while its twin draws comma-structure.

test_where_a_bracketed_member_reads_otherwise_than_its_twin records a census of these differences: 396 of 1,080 readings, by head. A later change that moves the count shows up there.

Docs

  • New rule rules/S13 (a bracketed member settled by its writing). It reads one signal, the position, and is a hub of S1, S3 and S6, the rules it cites for the writing and for the escape from the nickname. It has a Precedence bullet against S3's paired initials.
  • rules/S1: the member bullet now covers every spelling, and a new Precedence bullet names S13. The rule budget is re-recorded: S1 grows for that bullet, and S13 is new.
  • decisions/S13: the measurements, the reasons and each review round. It also records what was declined: escaping every member, and the twin reading by re-parsing.
  • Other decisions files: ma-do's 2026-07-17 entry is marked superseded in part. ma-do and suffix-acronym-collisions gain Elsewhere: lines, and vocabulary-model gets a Standing line and a phase 2l entry.
  • Also updated: the RFC's Brackets paragraph and mechanisms.md's CLAUSE-CONTENT-OVERRULES-DELIMITER.
  • User docs: a release-log bullet, plus usage.rst and customize.rst on bracketed ambiguous acronyms. AGENTS.md gains one sentence on a review lesson.

Measured against master (021028b, --base on a clean checkout; the same against 1353913)

  • Committed snapshot: 3 moves, each nickname → suffix with the report gone: John Smith (MA), Andrew Perkins (JD) and John Smith PhD (MA). It also adds S13's rule examples. Every CLDR, GND, Wikidata and conventions agreement record matches.
  • ctgov-officials: 3 of the 29 names holding one member alone in brackets move. Each is a capitals member in a mixed-case name, after a credential behind a comma (shapes Aa A Aa, AA (AA), Aa Aa, AaAaAa (AA), Aa Aa, Aa.AA(AA)), and each now reads as the credential it is. The other 26 are 23 Ed, 2 Ed. (already a suffix) and 1 ed.
  • FEC: 6 such names, all written in one case. None moves. The design spike that checked the word's own case moved all 6, wrongly.
  • tse-donors, ukec-individuals: match.
  • psc-individuals: its agreement record matches.
  • Dotted arm: no corpus holds a real name that uses it. It rests on the 2026-10-23 decision and on 1.4.0's reading.

Review

  1. First code review. The first draft decided in group, from the following word's suffix tag. So (MA) VI, (MA) Ph. D. and (MA) Dr. stayed nicknames while (MA) III escaped, and its per-member scans were quadratic. The fix moved the decision to post_rules, and the new bracket_members benchmark row fails on the first draft.
  2. Design-docs review. S1 claimed a report the parser did not make, and S13's Signal line named one signal of two.
  3. The twin reading, then one pass (Derek). A draft read a settled member exactly as its (PhD) twin by folding the pipeline to a fixed point. Two review rounds found it needed hooks in four stages. Derek chose the one-pass version instead, keeping S13's single signal, and the twin differences are recorded as accepted costs.
  4. Fixes kept from those rounds. A clause is the member alone only where its whole text is the member, so an emoji or zero-width character beside it leaves it a nickname, as its twin is. The draft's comma-structure fix is not needed in one pass: Smith, John, Jr. (M.A) reports nothing, as its twin does.
  5. Review of the one-pass commit. A clause in a name with no name word was being settled (Dr. (MA)), which S13's When rules out, so a name word is now required before the clause. That review also added a row for a leading period ((.ma)) and an S13 example for a stray full stop after the clause (John Smith (MA)., which keeps the nickname).

Each fix has case rows that fail on the commit before it. Two low edges are recorded in decisions/S13:

  • P6 after an empty-head comma (, Jones (MA) vd).
  • A word read as a name after the clause, where the twin's credential run would take it.

Checks

  • uv run pytest (26,854) and -n0 -m serial (43)
  • --python 3.15
  • mypy and ruff
  • sphinx-build -b doctest (0 failures) and README doctest

🤖 Generated with Claude Code

derek73 and others added 12 commits October 26, 2026 13:50
…hase 2l)

A member of the ambiguous credential class alone in brackets or quotes
after the name is the suffix where its writing settles it: a period
inside it (`John Smith (M.A)`), or capitals in a name of mixed case
(`John Smith (MA)`, `Andrew Perkins (JD)`), the case being the name's
own words' as rules/S6 asks it. Any other member stays the nickname and
reports suffix-or-nickname (`John Smith (Ed)`, `JOHN SMITH (MA)`), and
so does one with a name word after it (`Jeffrey (JD) Bricken`).

Decided in group, where the recorded case and the following words'
tags exist, and read as the suffix directly rather than unwrapped:
bare, `M.A` reads as paired initials (#872). The suffix-or-nickname
report moves from classify to group with the decision.

New rule rules/S13 (a bracketed member settled by its writing), since
the position it reads is evidence S1's signal does not; decisions/S13
records the measurements. Closes #810.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first draft decided in group and called any word after the clause
lacking the suffix tag a name word, so a suffix reached by shape (VI,
Ph. D., X.Y.Z., a capitals member), fils and a trailing title kept the
clause a nickname while their listed twins let it through. Deciding
first in post_rules, after the last given, middle or family token,
answers for every spelling; one bisect pass maps clauses to tokens, so
the pass is linear (test_benchmark's bracket_members row fails on the
first draft). Jack (MA) now keeps N3's family name.

A dotted member left a nickname inside the name is reported, as S1's
widened bullet says. S13's Signal names both its signals and a
Precedence bullet against S3; mechanisms.md's
CLAUSE-CONTENT-OVERRULES-DELIMITER names the second site; the
cross-file Standing clauses become Elsewhere lines; the ctgov count is
corrected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…810 second review)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e signal (#810)

Derek's two changes before the PR opens. A member rules/S13 settles now
reads as a bracketed unambiguous credential does in the same place,
fields and reports alike: post_rules records the settled clauses, and
run() folds the stages once more with them escaped in extract and their
word tagged as the credential's in classify (`Jack (MA)` reads given
'Jack', suffix 'MA', given-or-family, as `Jack (PhD)` does). A test
holds the invariant over comma shapes, heads and the three orders, its
negative control recorded (264 of 768 differ with a single fold).

S13 now reads only the position, citing S3 for the periods, S6 for the
capitals and S1 for the twin reading: its Signal line is a hub of S1,
S3 and S6. A maiden clause after a settled member is then taken into
the credential's run as after its twin, recorded as Accepted.

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

The fix-commit review found three places a settled member read
otherwise than its twin. One extra fold left a clause the second fold
settled a nickname with its report lost (JOHN SMITH (m.a) (MA)), so
run() folds until no new clause settles. Segment's tail test runs
before classify tags the settled word, so a dotted member past a
second comma drew a comma-structure report (Smith, John, Jr. (M.A));
the test leaves settled words out. "Alone in its clause" compares the
clause's text, as extract's escape does for the twin, so a dropped
character beside the member no longer lets it settle. Case rows pin
each, four failing on the previous commit; S13 cites every module it
lives in.

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

The fourth review found the previous commit's segment fix dropping the
settled word from the part past a second comma, which lost a report
the twin keeps (Smith, John, X.Y.Z. (MA)) and left the word out of the
report's text. The word now stays in the part: it passes the suffix
test and fails the shape-run test, as the listed credential it reads
as does. A case row pins it; stale "second fold" prose now says the
later folds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ket-escape-24a78d

# Conflicts:
#	docs/release_log.rst
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Derek chose the one-pass version: the re-parse loop that read a settled
member as its (PhD) twin cost a whole parse and machinery in four stages
for a shape that moves 6 real names. A settled clause becomes the
suffix in post_rules' single pass again, as 909026d had it; the
settled_clauses field, run()'s fixed point and the extract, classify
and segment hooks are gone, and frames are back near master's
(John Smith (MA) 210, master 214).

Kept: S13's one signal (position, citing S1, S3 and S6), and from the
reviews of the twin draft the text-equality "alone in its clause"
test, so a dropped character beside the member leaves it a nickname.
Its comma-structure fix is not needed in one pass, the part past a
second comma being tested while the clause is still a nickname.

Where the rest of the name then reads otherwise than its twin is
recorded as S13's Accepted bullets (Jack (MA), a maiden clause after
it, a clause only a second pass would settle, a part past a second
comma), and the twin test becomes a recorded census of the
differences (336 of 1,044 readings, by head).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review of the one-pass commit found every clause in a name with no
name word counting as "after the name" (Dr. (MA), (M.A) alone), which
S13's When rules out: a clause is settled only behind a name word now.
Adds rows for that and for a leading period, a Dr. head to the twin
census (re-recorded, 396 of 1,080), an S13 Except example for a stray
full stop after the clause, and corrects the "6 real names" count to
3 (ctgov's) and the re-measure's tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ket-escape-24a78d

# Conflicts:
#	docs/design/decisions/vocabulary-model.md
#	docs/release_log.rst
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 merged commit 4f033b7 into master Oct 27, 2026
12 checks passed
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.

Should John Smith (M.A) read M.A as a credential, as John Smith M.A does?

1 participant