The review round found the first draft shipped the inverse of the bug it
fixed. It let ANY piece open an entry, as the tail block always had --
safe there, because assign routes every tail piece to SUFFIX, which is
what `tail` means, and wrong off it, where a title piece routes to TITLE.
Two failures, one cause, neither visible to the gates that passed. The
`joined` tag is role-BLIND and the facade heals it for every role:
"Smith, Rev. Dr." title_list ['Rev.','Dr.'] -> ['Rev. Dr.']
"Smith Jr., Mr. Jr." suffix 'Jr., Jr.' -> 'Jr. Jr.'
The second glues a suffix backward across a comma the writer typed --
exactly what #429 exists to stop. The differential compares strings and
cannot see the first; the case table asserts the title STRING, which is
space-joined either way, and could not see it either.
Two joins that had been one, separated: WITHIN a piece the tag renders a
merged piece as one unit whatever role it holds; BETWEEN pieces it
continues an entry, and only a piece rendering into the same run may do
that. Sticky across a piece that is not in the entry, so an interleaved
title does not split its run ("Smith, MD Dr. PhD" -> 'MD PhD'); a
delimiter core still closes it.
Eight case rows and a facade test for the list views, which is the only
surface that shows the title collapse. Both regression guards verified
against a mutation copy -- they fail with the old condition restored.
Prose corrections, all measured by the reviewers:
- The round-trip claim was false AND backwards: str() of a fixed parse
is a no-comma string, which re-parses with the comma back. master was
the str-stable one. Struck from the release log and the case note.
- "one-word family comma" is not the condition -- there is no word-count
gate, so "John Smith, Jr. III" moves too (1.4.0's reading), as does a
title-led "Smith, Dr. MD PhD". Scope restated as it reads.
- The delimiter parity is #206 (021823e, "Apply suffix_delimiter only at
suffix-consumption sites"), NOT #191, the German/Dutch vocabulary PR.
Three code comments carried the error; corrected with it.
- The dormant-rule tell is #373's, and #426 the precedent for dropping a
shadowed rule -- neither #424 entry mentions it.
- "boundary example" in the entry and both ledgers: the example FIRES,
which is why the annotation came off.
- "filed rather than folded in" claimed an issue that does not exist.
C1 gains `_group.py` in `implemented:`, with the verbatim citation the
equality guard requires -- the whole-run half of the rule renders here.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Summary
Test plan