docs/design/mechanisms.md has no entry for a pattern this codebase has now executed five times and stated in prose twice.
The pattern
Two pipeline stages need the answer to the same question about the same input. Rather than each testing for itself, the site that does not own the decision calls the deciding stage's own predicate — so the two cannot drift.
The instances
| PR / issue |
what was shared |
what drifting had cost |
| #319 |
segment's suffix-comma predicate lifted into _vocab.is_wholly_suffix |
the comma decision and the honorific peel's segment test disagreed |
| #424 |
_is_leading_title / _leading_titles moved down into _group |
group's title() missed H2's unlisted abbreviations, so Xyz. van Johnson chained where Dr. van Johnson did not |
| #425 |
the S2 peel as _peel_trailing over _peel_walk, shared by assign and P5's reserve |
the reserve re-derived assign's peel by hand and missed the bare-acronym fork |
| #401 / #421 |
one reads_as_suffix predicate |
four inexact-mirror drafts caught in review |
| #429 |
_segment_holds_no_name moved down into _group |
group asked by segment index while assign asked by content |
The principle is already written down twice in decisions.md — "so the comma decision and the honorific peel's segment test cannot drift apart" (#319) and "the reserve and the join ask the same question, and it is the one assign answers" (#401/#421) — but only ever inside a dated entry about a specific fix, where nobody looks it up.
Why an entry is worth writing
Existing mechanisms.md entries are seated on two or three instances. This one has five and keeps recurring: four consecutive PRs (#424, #425, #401/#421, #429) each rediscovered it. Naming it would make the next one a lookup rather than a discovery.
The Known-limit clause, which is the interesting half
The share is only available in the import direction. _assign imports _group, so a predicate both stages ask must live in _group. Where the earlier stage needs the later stage's answer, sharing a predicate is the only option — recording the decision on the state is structurally unavailable.
ParseState.order is the contrast and states the alternative in its own docstring: "Recorded rather than recomputed downstream, because the two can differ and a post_rules rule keyed on policy.name_order would then disagree with the roles assign already wrote (#395)." But order is recorded by assign for post_rules — a later reader. That option exists only when the reader comes after the decider.
The measured cost of the predicate form, from #429: _segment_holds_no_name now runs twice per family-comma parse, worth 1.2–2.2% of such a parse and 0% of every other. Cheap enough to accept, and worth recording in the entry so the next instance does not re-measure it.
Also worth noting in the entry
_group.py is 1037 lines and now hosts five predicates that belong to neither stage — _is_suffix_piece, _peel_walk/_peel_trailing, _leading_titles, _is_leading_title, _segment_holds_no_name — living there only because of the import direction. That is #439.
Came out of the cleanup review of #435.
docs/design/mechanisms.mdhas no entry for a pattern this codebase has now executed five times and stated in prose twice.The pattern
Two pipeline stages need the answer to the same question about the same input. Rather than each testing for itself, the site that does not own the decision calls the deciding stage's own predicate — so the two cannot drift.
The instances
segment's suffix-comma predicate lifted into_vocab.is_wholly_suffix_is_leading_title/_leading_titlesmoved down into_grouptitle()missed H2's unlisted abbreviations, soXyz. van Johnsonchained whereDr. van Johnsondid not_peel_trailingover_peel_walk, shared by assign and P5's reservereads_as_suffixpredicate_segment_holds_no_namemoved down into_groupThe principle is already written down twice in
decisions.md— "so the comma decision and the honorific peel's segment test cannot drift apart" (#319) and "the reserve and the join ask the same question, and it is the one assign answers" (#401/#421) — but only ever inside a dated entry about a specific fix, where nobody looks it up.Why an entry is worth writing
Existing
mechanisms.mdentries are seated on two or three instances. This one has five and keeps recurring: four consecutive PRs (#424, #425, #401/#421, #429) each rediscovered it. Naming it would make the next one a lookup rather than a discovery.The Known-limit clause, which is the interesting half
The share is only available in the import direction.
_assignimports_group, so a predicate both stages ask must live in_group. Where the earlier stage needs the later stage's answer, sharing a predicate is the only option — recording the decision on the state is structurally unavailable.ParseState.orderis the contrast and states the alternative in its own docstring: "Recorded rather than recomputed downstream, because the two can differ and a post_rules rule keyed onpolicy.name_orderwould then disagree with the roles assign already wrote (#395)." Butorderis recorded by assign forpost_rules— a later reader. That option exists only when the reader comes after the decider.The measured cost of the predicate form, from #429:
_segment_holds_no_namenow runs twice per family-comma parse, worth 1.2–2.2% of such a parse and 0% of every other. Cheap enough to accept, and worth recording in the entry so the next instance does not re-measure it.Also worth noting in the entry
_group.pyis 1037 lines and now hosts five predicates that belong to neither stage —_is_suffix_piece,_peel_walk/_peel_trailing,_leading_titles,_is_leading_title,_segment_holds_no_name— living there only because of the import direction. That is #439.Came out of the cleanup review of #435.