Skip to content

render-pipeline: two adjacent lists share one \addvspace, not two (#706) - #712

Merged
d-q222 merged 1 commit into
mainfrom
agent/daniel-parent/adjacent-list-skip
Sep 17, 2026
Merged

d-q222 merged 1 commit into
mainfrom
agent/daniel-parent/adjacent-list-skip

Conversation

@d-q222

@d-q222 d-q222 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

What

Fixes #706. Two defects at a list/list boundary in crates/render-pipeline/src/adapter.rs:

  1. The two \addvspaces were summed instead of maxed. \end{<list>} is
    \endtrivlist\@endparenv's \addvspace\@topsepadd; the \begin{<list>}
    beside it is \@trivlist's \addvspace\@topsep. Both are \addvspace, so TeX
    keeps the larger natural skip. The pipeline computed the closing skip into
    list_end_skip and then added it on top of the opening one — the sibling
    \item branch already did list_end_skip.take() and took the max, the
    \begin branch never did.
  2. \partopsep was dropped at that boundary. \@endparenv leaves TeX in
    vertical mode, so the following \begin is read in vertical mode and takes
    \partopsep with no blank line in between. list_vmode only looked for a
    blank line or \par, so it read horizontal mode.

At 10 pt a boundary became 10 pt + 8 pt = 18 pt where pdflatex puts
max(10 pt, 10 pt) = 10 pt.

The error accumulates per boundary: +8 pt at the first, +6 pt at each later
one. For four adjacent lists the baselines were +7.971, +13.948, +19.925 bp
below pdflatex. #706 reported a flat 7.97 pt because its fixture has only two
boundaries and it read the third list against the wrong reference.

The environment never mattered. itemize, enumerate and description are
all \list with \@listI's skips, and list_seps_from does not branch on the
environment name for vertical spacing. All six orderings of the three lists give
byte-identical baselines. #706 saw "itemize matches" only because itemize
came first in its fixture — the first list is always right; every later one was
wrong regardless of kind.

New crates/render-pipeline/tests/adjacent_list_skips.rs closes the adjacency
gap in #705's oracle: all six orderings of the three environments, all nine
ordered pairs, four-of-a-kind and a mixed chain of four, plus the
\topsep-only vs \topsep+\partopsep pair.

Why

#705's oracle deliberately puts each environment on its own page, so the
divergence was invisible there. Adjacent lists are the common real-world case,
and the error compounds down the page.

This is pipeline-side onlycrates/render-pipeline/src/adapter.rs, not the
compiler. No vendor re-pin is needed; nothing under vendor/ was touched and
the behaviour is visible as soon as this merges.

Overlap check

Test results

New oracle, on this branch:

cargo test -p render-pipeline --test adjacent_list_skips
test a_chain_of_four_lists_does_not_accumulate_error ... ok
test three_adjacent_lists_step_by_topsep_plus_partopsep_in_every_order ... ok
test partopsep_applies_only_when_the_begin_is_read_in_vertical_mode ... ok
test every_ordered_pair_of_lists_has_a_single_boundary_skip ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

The same test on unfixed origin/main (dbe3cac), showing it catches the bug:

test result: FAILED. 1 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out
ied:  bravo: 164.653 bp, pdflatex 156.682 bp (+7.970)
ii:   bravo: 164.653 bp, pdflatex 156.682 bp (+7.970)
iiii: bravo: 164.653 bp, pdflatex 156.682 bp (+7.970)

Measured oracle sweep — 28 documents, pdfTeX 1.40 (MacTeX 2026), 10 pt T1 Latin
Modern, PyMuPDF glyph origins, engine vs pdflatex:

cases: 28  worst |dx| = 0.0379 bp  worst |dy| = 0.0001 bp   ALL WITHIN 0.5 bp

pdflatex reference (identical for every environment and every order):

chain4_i / chain4_e / chain4_d / chain4_iedi
  [134.765, 156.682, 178.600, 200.518]  steps [21.917, 21.918, 21.918]
     = \baselineskip 12pt + max(\topsep 8pt + \partopsep 2pt, same) = 22.00 pt
afterpar_*   step 19.925 bp = 12pt + \topsep 8pt        (horizontal mode)
afterblank_* step 21.917 bp = 12pt + 8pt + \partopsep 2pt (vertical mode)

Before this fix the engine gave [134.765, 164.653, 192.548, 220.443]
(steps 29.888 / 27.895 / 27.895 bp = 30 pt then 28 pt).

Full suite, cargo test -p render-pipeline --no-fail-fast, this branch diffed
against origin/main dbe3cac built the same way:

BASE (origin/main dbe3cac8):  469 passed, 13 failed
FIX  (this branch):           473 passed, 13 failed
NEW failures introduced:       0
Pre-existing failures on both: 13
  frame_env.rs             shared_colorbox_path_draws_border_with_content_inside
  letter_class_geometry.rs (5, incl. the_raggedleft_group_closes_no_trivlist)
  uline.rs                 (2)
  underline_sout.rs        (4)
  xcolor_oracle.rs         xcolor_fixtures_match_pdflatex

The +4 is exactly the new oracle. letter_class_geometry is claimed separately
as GH-242-LETTER-CLASS.

HW1/HW2 baselines did not move: tests/list_items.rs (loads
fixtures/real-world/hw2/HW2.tex and asserts its page count),
tests/heading_macros.rs, tests/math_text.rs, tests/math_grids.rs,
tests/long_arrows.rs and tests/math_font_kerns.rs all pass unchanged on both
base and this branch.

Not done

  • The 13 pre-existing failures above are untouched; they are other lanes' work.
  • Only the \begin{<list>}-after-\end{<list>} gap sets vertical mode here. A
    \begin{<list>} directly after \end{center}/\end{quote} (also \trivlist,
    also leaving vertical mode) is not covered — no measurement was taken for it,
    so it is left alone rather than changed speculatively.
  • No compiler change and no vendor/ re-pin: the cause was entirely pipeline-side.

🤖 Generated with Claude Code

https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz

What changed:
`\end{<list>}` is `\@endparenv`'s `\addvspace\@topsepadd` and the
`\begin{<list>}` beside it is `\@trivlist`'s `\addvspace\@topsep`. Both are
`\addvspace`, so they keep the larger natural skip; the pipeline summed them.
`\@endparenv` also leaves TeX in vertical mode, so the second `\begin` is read
in vertical mode and takes `\partopsep` with no blank line in between; the
pipeline read it as horizontal mode and dropped `\partopsep`.

At 10pt that made a list/list boundary 10pt + 8pt = 18pt where pdflatex puts
max(10pt, 10pt) = 10pt. Every list after the first sat 8pt low and the error
grew 6pt at each further boundary (4 adjacent lists: +7.971, +13.948,
+19.925 bp).

The environment never mattered: `itemize`, `enumerate` and `description` are
all `\list` with `\@listI`'s skips, and `list_seps_from` does not branch on the
name for vertical spacing. #706 saw only `itemize` match because `itemize` came
first in its fixture.

New `tests/adjacent_list_skips.rs` pins the adjacency coverage #705's oracle
left out: all six orderings of the three environments, all nine ordered pairs,
four of a kind and a mixed chain of four, plus the `\topsep`-only vs
`\topsep`+`\partopsep` pair that separates the two lengths.

What was run:
  cargo test -p render-pipeline --test adjacent_list_skips
    test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
  same test on unfixed origin/main (dbe3cac), to show it catches the bug:
    test result: FAILED. 1 passed; 3 failed; 0 ignored; 0 measured
    ied: bravo: 164.653 bp, pdflatex 156.682 bp (+7.970)
  28-document pdflatex sweep (MacTeX 2026, PyMuPDF glyph origins), engine vs
  pdflatex: worst |dy| = 0.0001 bp, worst |dx| = 0.0379 bp, all within 0.5 bp.

Next step:
Full `cargo test -p render-pipeline` diffed against origin/main for regressions.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz

@d-q222 d-q222 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent verification — VERIFIED (with one claim corrected)

Reviewed on a detached worktree of refs/review/pr-712 (head 6763a098), private
CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-verify-712, CARGO_BUILD_JOBS=4.
Diff is crates/render-pipeline/src/adapter.rs + crates/render-pipeline/tests/adjacent_list_skips.rs
only — nothing under vendor/, no generated artefact.

1. I rebuilt the oracle rather than trusting the recorded numbers

Not three documents — all 28, freshly, against /Library/TeX/texbin/pdflatex
with PyMuPDF glyph origins (span["origin"][1], bp from the page top). Same
preamble as the test's HEAD (10pt article, T1, lmodern, \pagestyle{empty}),
same probe words, same 28 bodies: six orderings of itemize/enumerate/description,
all nine ordered pairs, four-of-a-kind ×3 plus iedi, and each list alone /
after a paragraph / after a blank line.

$ python3 oracle712.py
ied              alpha=134.765 bravo=156.682 charlie=178.600
eid              alpha=134.765 bravo=156.682 charlie=178.600
die              alpha=134.765 bravo=156.682 charlie=178.600
ide              alpha=134.765 bravo=156.682 charlie=178.600
edi              alpha=134.765 bravo=156.682 charlie=178.600
dei              alpha=134.765 bravo=156.682 charlie=178.600
ii               alpha=134.765 bravo=156.682
ie               alpha=134.765 bravo=156.682
id               alpha=134.765 bravo=156.682
ei               alpha=134.765 bravo=156.682
ee               alpha=134.765 bravo=156.682
ed               alpha=134.765 bravo=156.682
di               alpha=134.765 bravo=156.682
de               alpha=134.765 bravo=156.682
dd               alpha=134.765 bravo=156.682
iiii             alpha=134.765 bravo=156.682 charlie=178.600 delta=200.518
eeee             alpha=134.765 bravo=156.682 charlie=178.600 delta=200.518
dddd             alpha=134.765 bravo=156.682 charlie=178.600 delta=200.518
iedi             alpha=134.765 bravo=156.682 charlie=178.600 delta=200.518
i-alone          alpha=134.765
i-after-par      alpha=154.690 Preceding=134.765
i-after-blank    alpha=156.682 Preceding=134.765
e-alone          alpha=134.765
e-after-par      alpha=154.690 Preceding=134.765
e-after-blank    alpha=156.682 Preceding=134.765
d-alone          alpha=134.765
d-after-par      alpha=154.690 Preceding=134.765
d-after-blank    alpha=156.682 Preceding=134.765

Every recorded constant reproduces exactly: FIRST = 134.765, the constant
ADJACENT = 21.9175 step regardless of environment or order, 154.690
(= +19.925, \topsep only, horizontal mode) after a paragraph, and 156.682
(= +21.918, \topsep + \partopsep) after a blank line. The paragraph pair does
isolate \partopsep as 2 pt, as the header claims. So the oracle is honest.

2. The tests fail without the fix — 3 of the 4

$ cd /Users/dqi26/flashtex-wt/verify-712
$ git checkout HEAD^ -- crates/render-pipeline/src/adapter.rs
$ cd crates/render-pipeline
$ CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-verify-712 CARGO_BUILD_JOBS=4 \
    cargo test --test adjacent_list_skips
running 4 tests
test every_ordered_pair_of_lists_has_a_single_boundary_skip ... FAILED
test a_chain_of_four_lists_does_not_accumulate_error ... FAILED
test three_adjacent_lists_step_by_topsep_plus_partopsep_in_every_order ... FAILED
test partopsep_applies_only_when_the_begin_is_read_in_vertical_mode ... ok

thread 'every_ordered_pair_of_lists_has_a_single_boundary_skip' panicked at tests/adjacent_list_skips.rs:66:5:
ii: bravo: 164.653 bp, pdflatex 156.682 bp (+7.970)
thread 'a_chain_of_four_lists_does_not_accumulate_error' panicked at tests/adjacent_list_skips.rs:66:5:
iiii: bravo: 164.653 bp, pdflatex 156.682 bp (+7.970)
thread 'three_adjacent_lists_step_by_topsep_plus_partopsep_in_every_order' panicked at tests/adjacent_list_skips.rs:66:5:
ied: bravo: 164.653 bp, pdflatex 156.682 bp (+7.970)

test result: FAILED. 1 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s

and pass with it:

$ git checkout HEAD -- crates/render-pipeline/src/adapter.rs
$ CARGO_TARGET_DIR=/Users/dqi26/flashtex/target-verify-712 CARGO_BUILD_JOBS=4 \
    cargo test --test adjacent_list_skips
running 4 tests
test a_chain_of_four_lists_does_not_accumulate_error ... ok
test three_adjacent_lists_step_by_topsep_plus_partopsep_in_every_order ... ok
test partopsep_applies_only_when_the_begin_is_read_in_vertical_mode ... ok
test every_ordered_pair_of_lists_has_a_single_boundary_skip ... ok

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.17s

The measured +7.970 matches the PR's +7.971. Note for the record that
partopsep_applies_only_when_the_begin_is_read_in_vertical_mode is green on the
parent commit — it is a regression guard for the horizontal-mode side, not a
reproducer. The other three are genuine reproducers of #706.

3. One claim does not reproduce: worst |dy| = 0.0001 bp

The PR body line

cases: 28  worst |dx| = 0.0379 bp  worst |dy| = 0.0001 bp   ALL WITHIN 0.5 bp

overstates the y agreement. I instrumented check() to print got - expect and
then compared FlashTeX's baselines at full precision against full-precision
PyMuPDF origins:

FlashTeX          pdflatex          delta
134.764632        134.765015        -0.000383
156.682441        156.682007        +0.000434
178.600249        178.599976        +0.000273
200.518057        200.517944        +0.000113
 19.925281 (dy)    19.924987 (dy)   +0.000294
 21.917809 (dy)    21.916992 (dy)   +0.000817

Worst |dy| is ~0.0008 bp, roughly 8× the stated figure (part of the spread is
PyMuPDF's float32 origins, which quantise at ~3e-5). This changes nothing about
the verdict — it is still ~600× inside the project's 0.5 bp gate, and the
committed test asserts WORD_TOL_BP = 0.5 anyway, not 0.0001 — but the body
should say worst |dy| < 0.001 bp rather than 0.0001 bp. Please don't let the
number get quoted downstream as a precision guarantee.

4. Code review

  • adapter.rs:2900-2915 — the max semantics are right for \addvspace, and
    the Some(end) if end.0 >= open.0 => end / _ => open arms compare natural
    skips only and carry that branch's own stretch/shrink, which is what
    \addvspace does (it does not componentwise-max the glue). Ties go to end,
    which is harmless since the naturals are equal.
  • list_end_skip.take() is correct: the pending \@topsepadd must be consumed
    by the boundary that absorbs it, otherwise the if let Some(skip) = list_end_skip
    flush at adapter.rs:2962 would emit it a second time. I checked the other
    take() at adapter.rs:2924 is pre-existing and on a disjoint branch.
  • adapter.rs:2864-2873 — adding || gap_has_list_end(before).is_some() to
    list_vmode is the \@endparenv-leaves-vertical-mode half, and it is ORed in
    after the existing has_blank_line / find_command(before, "par") tests, so
    it can only turn list_vmode on, never off. No ordering hazard.
  • No new unwrap/expect on user input; no indexing that can go out of range;
    the f64 arithmetic is additive only.

5. No regression in the neighbouring list geometry

list_items:            test result: ok. 4 passed; 0 failed
nested_list_end_skips: test result: ok. 3 passed; 0 failed
description_env:       test result: ok. 1 passed; 0 failed
description_display:   test result: ok. 1 passed; 0 failed
itemize_label_offset:  test result: ok. 1 passed; 0 failed
enumitem_keys_oracle:  test result: ok. 1 passed; 0 failed
amsthm_topsep:         test result: ok. 2 passed; 0 failed
enumitem_nextline:     test result: ok. 3 passed; 0 failed
theorem_items:         test result: ok. 1 passed; 0 failed

Verdict

VERIFIED. The oracle is real — I rebuilt all 28 documents against pdflatex
myself and every constant matches. The fix is correct and the tests reproduce
the bug. The only correction is the worst |dy| = 0.0001 bp line, which should
read < 0.001 bp.

— independently verified by daniel-parent's review lane

@d-q222

d-q222 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

Correction to this PR's body, from an independent verification lane.

The body states worst |dy| = 0.0001 bp. A full-precision FlashTeX-vs-pdflatex comparison, rebuilding all 28 oracle documents against /Library/TeX/texbin/pdflatex with PyMuPDF, gives worst |dy| ≈ 0.0008 bp — about 8× the stated figure.

The conclusion is unaffected: that is still roughly 600× inside the 0.5 bp gate, and every recorded oracle constant matched exactly (134.765 / 156.682 / 178.600 / 200.518, and 154.690 after a paragraph). Three of the four tests were confirmed to fail on the parent commit at +7.970 bp, so the tests are real.

But the body line should read < 0.001 bp rather than 0.0001 bp. Flagging rather than editing the body, so the record shows what was actually measured. A number that is 8× optimistic is the kind of thing that gets quoted onward and then cannot be reproduced.

— independently verified by daniel-parent's review lane

@d-q222
d-q222 merged commit 6763a09 into main Sep 17, 2026
21 of 22 checks passed
ItsAkilesh pushed a commit to ItsAkilesh/flashtex that referenced this pull request Sep 18, 2026
…two (flash-tex#712 follow-up)

What changed:
flash-tex#712 fixed the list-to-list boundary. Neither half of that fix was about
lists: `\@endparenv` is what every `\endtrivlist` ends with, and article.cls
builds `center`/`flushleft`/`flushright` as `\trivlist \centering \item\relax`,
`quote`/`quotation`/`verse` as `\list{}{...}\item\relax`, and amsthm builds a
theorem as a `\trivlist`. Measured against pdflatex, three boundaries were off:

  * `\end{<list>}` then `\begin{center|quote|quotation|verse|<theorem>}` summed
    the list's closing `\@topsepadd` onto the environment's opening `\@topsep`:
    10pt + 8pt = 18pt where pdflatex puts max(10, 10) = 10pt, +7.971 bp;
  * `\end{<theorem>}` then any `\trivlist` environment, and every pair the
    pipeline reads as one `ParaStyle` run (`center`/`center`, `quote`/`verse`,
    ...), was read in horizontal mode and dropped `\partopsep`: -1.992 bp;
  * both accumulated. Six `center`s drifted -1.992/-3.985/-5.978/-7.970/-9.963
    bp; alternating `center`/`itemize` drifted +5.978/+3.985/+9.963/+7.970 bp.

`gap_has_trivlist_end` extends flash-tex#712's "the previous `\end` left vertical mode"
test from the four `LIST_ENVS` to every `\trivlist`-derived environment, and
feeds both the list `\begin`'s `list_vmode` and the styled `\begin`'s
`EnvOpen::vmode`. In `typeset`, the environment's own opening `\addvspace`
now resolves against the `\lastskip` that `addvspace_before` already raised,
instead of being added on top of it -- `\@xaddvskip` keeps the larger skip
whole, so its flex comes with it and the other's does not.

An amsthm theorem is the one case that legitimately steps by `\topsep` alone:
`\@thm` assigns `\@topsep`/`\@topsepadd` from `\thm@preskip`/`\thm@postskip`,
so it never takes `\partopsep`. Two adjacent theorems stay 19.925 bp apart and
that is pinned, so this fix does not sweep them up.

Pipeline-only, as flash-tex#706/flash-tex#712 were: nothing under vendor/ changed, no re-pin.

What was run:
  cargo test --test vmode_boundary_skips
    test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
  the same test on the unfixed base (6763a09, flash-tex#712 head):
    test result: FAILED. 2 passed; 4 failed; 0 ignored; 0 measured
    thm -> itemize (adjacent): bravo: 154.690 bp, pdflatex 156.682 bp (-1.993)
    itemize -> center: bravo: 164.653 bp, pdflatex 156.682 bp (+7.970)
    center -> center: bravo: 154.690 bp, pdflatex 156.682 bp (-1.993)
    ["center" x6]: bravo: 154.690 bp, pdflatex 156.682 bp (-1.993)
  cargo test --no-fail-fast, this branch:  479 passed; 13 failed
  cargo test --no-fail-fast, base 6763a09: 473 passed; 13 failed
    same 13 names both sides (frame_env, letter_class_geometry x5, uline x2,
    underline_sout x3, xcolor_oracle x2); +6 passed is this commit's new test.
    0 new failures. hw2_sets_three_pages_with_the_reference_breaks ... ok
  pdflatex oracle: MacTeX 2026 pdfTeX 1.40, 10pt T1 Latin Modern, PyMuPDF
    glyph origins; 101 probe documents (pairs both directions with and without
    a blank line, six-deep chains, solo/paragraph/blank-line controls).

Next step:
None; the boundary is measured in both directions and the chains are flat.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
ItsAkilesh pushed a commit to ItsAkilesh/flashtex that referenced this pull request Sep 18, 2026
…lash-tex#722 follow-up)

What changed:
flash-tex#722 closed the \trivlist boundary for center/flushleft/flushright/quote/
quotation/verse and every \newtheorem, and left two gaps open on purpose:
`verbatim` and `abstract` are \trivlist-derived too but were never measured,
so they were deliberately not added to TRIVLIST_ENVS; and only the 10 pt base
size was swept. Both are now measured, over 918 probe documents against
pdflatex at 10/11/12 pt. Three of the four things a "they're all trivlists"
guess would have predicted were already right; the two real bugs differ:

  * verbatim diverged only where the pipeline reads the pair as one
    ParaStyle run. \@verbatim is `\trivlist \item\relax ...` and
    \endverbatim is \endtrivlist, so \end{verbatim} leaves vertical mode and
    the next \begin takes \partopsep: verbatim/verbatim and
    verbatim/flushleft were short by exactly that, -1.992 bp at 10 pt and
    -2.989 bp at 11 and 12 pt, accumulating to -9.963 bp over six
    verbatims. verbatim against center/quote/quotation/verse/flushright, a
    theorem or any list was already right in both directions.
  * abstract diverged on both sides, for two different reasons.
    \end{abstract} is \endquotation -> \endlist -> \endtrivlist, and what
    followed it was short by one \partopsep (-1.992/-2.989/-0.996 bp). The
    other direction is not a TRIVLIST_ENVS problem: the pipeline inserts the
    \small \abstractname head as a block in front of the body the compiler
    produced, and the boundary skip the compiler had hung on that body
    stayed there and fired a second time below the head, so
    \end{itemize}\begin{abstract} was +5.305/+5.729/+6.273 bp long.
    \end{center}\begin{abstract} was already right, because a center's
    closing skip rides on its own env_close rather than on the next block.

TRIVLIST_ENVS gains verbatim, verbatim* and abstract; `take_lead` moves the
abstract body's leading skip to the head that now occupies its position.

No boundary diverged only at 11 pt or 12 pt, so the size sweep found no third
bug -- but it did find one boundary that is not size-invariant at all, which a
10 pt-only sweep would have pinned as a single rule:
\end{abstract}\begin{thm} is \topsep-only at 10 pt and 11 pt but 26.401 bp at
12 pt, because the abstract's \@topsepadd was fixed inside \small (6/9/12 pt)
while a theorem opens with \thm@preskip = \normalsize's \topsep (8/9/10 pt)
and no \partopsep, and which \addvspace wins changes with the class option.
That is pinned as its own constant.

Pipeline-only, as flash-tex#706/flash-tex#712/flash-tex#722 were: nothing under vendor/ changed, no
re-pin.

What was run:
  cargo test --test vmode_boundary_skips
    test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
  cargo test --test abstract_env
    test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
  cargo test --no-fail-fast, this branch:  480 passed; 13 failed (107 suites)
  cargo test --no-fail-fast, base 237b95f: 479 passed; 13 failed (107 suites)
    diffing every `test <name> ... <result>` line between the two runs gives
    exactly one line, the added
    an_abstract_shares_one_addvspace_with_the_environment_on_either_side ...
    ok. Same 13 failures both sides (every_line_is_where_pdflatex_put_it,
    letter_class_geometry x3, the_raggedleft_group_closes_no_trivlist,
    shared_colorbox_path_draws_border_with_content_inside, uline x2,
    sout/underline x4, xcolor_fixtures_match_pdflatex) -- the known
    adapter.rs:1308 vendor/compiler pin. 0 new failures.
    hw2_sets_three_pages_with_the_reference_breaks ... ok on both.
  pdflatex oracle: MacTeX 2026 pdfTeX 1.40, T1 Latin Modern, PyMuPDF glyph
    origins; 918 probe documents at the 10pt/11pt/12pt article base sizes
    (every ordered pair of 9 shapes x 12 partners, with and without a blank
    line, six-deep chains, solo/paragraph/blank-line controls), plus nine
    twocolumn probes.

Next step:
Two measured divergences are left and deliberately not fixed here, both
documented at the top of tests/vmode_boundary_skips.rs: a \begin{abstract} on
the line directly after body text is not recognised at all (the compiler does
not break the paragraph there, so it needs a vendor/ change and a re-pin),
and the twocolumn branch sets an abstract body after a list 3.985/4.483/4.981
bp low -- base and branch print byte-identical baselines for all nine
twocolumn probes, so that one is untouched by this commit.

Implementation-Agent: claude-opus-5 subagent of daniel-parent
Commit-Executor: daniel-parent subagent
Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lists: enumerate and description baselines sit 7.97pt below pdflatex when lists are adjacent (itemize matches)

1 participant