Skip to content

docs(design): name the pattern five PRs rediscovered (#438) - #440

Merged
derek73 merged 1 commit into
masterfrom
docs/438-two-stages-one-question
Aug 25, 2026
Merged

docs(design): name the pattern five PRs rediscovered (#438)#440
derek73 merged 1 commit into
masterfrom
docs/438-two-stages-one-question

Conversation

@derek73

@derek73 derek73 commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Closes #438.

mechanisms.md had no entry for "two stages need the same answer about the same input", though the codebase has executed the pattern five times and decisions.md states the principle twice — each time inside a dated entry about a specific fix, where nobody looks it up.

The entry

ONE-PREDICATE-PER-QUESTION — the stage that does not decide calls the one that does.

The site that does not own the decision calls the deciding stage's own predicate, never a condition written to match it. A hand-written mirror agrees with its original until one of them moves, and the drift is invisible in both directions: each site keeps passing its own tests while they disagree about an input neither covers.

The five instances, each found as a defect before it was found as a pattern:

shared what drifting cost
#319 is_wholly_suffix_vocab the comma decision and the honorific peel's segment test disagreed
#401/#421 is_trailing_numeral_suffix_vocab the reserve carried a copy of assign's fork
#425 _peel_walk / _peel_trailing the reserve re-derived assign's peel by hand
#424 _is_leading_title / _leading_titles_group group's title() missed H2's unlisted abbreviations
#429 _segment_holds_no_name_group group asked by segment index, assign by content

The Known-limit clause is the half worth writing down

The share is only available in the import direction. _assign imports _group, so a piece-level predicate both stages ask has to live in _group — not because grouping owns it. A text-level one goes to _vocab instead: the destination follows the layer, not the topic.

Where the reader comes after the decider, the alternative is to record the answer on the state — ParseState.order is exactly that shape, and says so in its own docstring. That option is unavailable whenever the earlier stage is the one asking, which is what made #429's design a discovery rather than a lookup.

One citation added

_group.py's module docstring restated the import-direction claim in free prose — which the mechanisms preamble names as the failure mode: "Free-prose restatements of mechanism claims are how one wrong sentence has shipped six times." It cites the slug now.

Two claims corrected while writing it

Both were carried from session notes rather than the committed record, and both were caught by running axis 1 (recompute every number) and axis 4 (claims about a document vs what it says) on my own draft:

Verification

Docs-and-one-comment only. Suite 5668 passed, mypy and ruff clean, differential 0 unexplained at the default baseline (unchanged, as expected for a change that alters no parse).

Axes run: 1 (recompute — found both corrections above), 2 (no detector used), 4 (every quoted excerpt checked verbatim against its source — #319's decisions line, ParseState.order's docstring, the mechanisms preamble), 7 (the "Reach for it when" clause is advisory and sweeps in nothing), 9 (the new anchor resolves; the citation test passes). Axes 3, 5, 6 are rules.md-specific and inapplicable — no rule statement, example or interacts: line changed. Axis 8 inapplicable: no guard added. Axis 10: the entry's only capability claim is that _assign imports _group and cannot be imported back, verified.

🤖 Generated with Claude Code

mechanisms.md had no entry for "two stages need the same answer about
the same input", though the codebase has executed it five times and
decisions.md states the principle twice inside dated entries about
specific fixes, where nobody looks it up.

ONE-PREDICATE-PER-QUESTION: the site that does not own the decision
calls the deciding stage's own predicate, never a condition written to
match it. A hand-written mirror agrees with its original until one of
them moves, and the drift is invisible in both directions -- each site
keeps passing its own tests while disagreeing about an input neither
covers.

The Known-limit clause is the half worth writing down. The share is only
available in the IMPORT direction: assign imports group, so a piece-level
predicate both stages ask must live in group. Where the reader comes
after the decider, the alternative is to record the answer on the state
(ParseState.order is that shape) -- unavailable whenever the earlier
stage is the one asking. That asymmetry is what made #429's design a
discovery rather than a lookup.

_group.py's module docstring restated the import-direction claim in free
prose, which the mechanisms preamble names as the failure mode ("Free-
prose restatements of mechanism claims are how one wrong sentence has
shipped six times"). It cites the slug now.

Two claims corrected against the record while writing it, both of which
I had carried from session notes rather than the docs:

- #401/#421's `reads_as_suffix` no longer exists -- #425 superseded it
  with the shared peel -- so that pair's lasting artifact is
  `is_trailing_numeral_suffix`, and the entry names that instead.
- "four inexact-mirror drafts" and "twice the right answer" are counts
  no committed document supports. The record carries the lesson (mirror
  assign's WALK, not its condition) but not the tally, so the entry
  states the lesson without the number.

Closes #438

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@derek73 derek73 added the docs Documentation fixes and updates label Aug 25, 2026
@derek73 derek73 self-assigned this Aug 25, 2026
@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.59%. Comparing base (43dc150) to head (3a0a11c).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #440   +/-   ##
=======================================
  Coverage   98.59%   98.59%           
=======================================
  Files          44       44           
  Lines        3064     3064           
=======================================
  Hits         3021     3021           
  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
derek73 merged commit fcebf79 into master Aug 25, 2026
10 checks passed
@derek73
derek73 deleted the docs/438-two-stages-one-question branch August 26, 2026 02:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation fixes and updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mechanisms.md has no entry for "two stages, one question" — the pattern five PRs have now rediscovered

1 participant