render-pipeline: verbatim and abstract are \trivlist boundaries too (#722 follow-up) - #728
Conversation
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
…two (#712 follow-up) What changed: #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 #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 #706/#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, #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
…722 follow-up) What changed: #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 #706/#712/#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
d-q222
left a comment
There was a problem hiding this comment.
Independent verification — VERIFIED
Reviewed at a12ec1d3, base 237b95fa (#722). Worktrees ~/flashtex-wt/vrfy-728 and
~/flashtex-wt/vrfy-722, per-PR CARGO_TARGET_DIR=…/target-vrfy-728 and
…/target-vrfy-722, CARGO_BUILD_JOBS=4, fetched as
git fetch origin pull/N/head:refs/review/pr-N.
I was pointed at this PR to confirm a claimed self-caught regression in the
two-column abstract. That regression does not exist, and — importantly — this PR
never claims it does; it says the opposite, twice, and the measurement backs the PR.
The claim it does make (a line-by-line test diff) reproduces exactly.
1. Line-by-line test diff — VERIFIED, to the line
Whole crates/render-pipeline suite, --no-fail-fast, debug, both sides:
$ cargo test --no-fail-fast # branch a12ec1d3
$ cargo test --no-fail-fast # base 237b95fa
$ grep -oE '^test [A-Za-z0-9_:]+ \.\.\. [a-zA-Z]+' <log> | sort > <side>.lines
$ diff base.lines branch.lines
111a112
> test an_abstract_shares_one_addvspace_with_the_environment_on_either_side ... ok
base lines: 496
branch lines: 497
base: passed=479 failed=13 suites=107
branch: passed=480 failed=13 suites=107
Exactly one added line, zero changed lines, in either direction. That is the claim
the PR makes and it holds. The 13 failures are name-for-name identical on both sides:
$ diff <(grep '\.\.\. FAILED' base.log | sort) <(grep '\.\.\. FAILED' branch.log | sort)
(no output)
every_line_is_where_pdflatex_put_it opening_lines_are_one_paragraph_not_one_each
letter_paragraph_gaps_are_the_class_parskip page_one_texttop_fil_pushes_the_first_baseline_down
the_raggedleft_group_closes_no_trivlist shared_colorbox_path_draws_border_with_content_inside
sout_paints_a_rule sout_with_ulem_is_not_an_unsupported_error
text_mode_underline_paints_a_rule text_mode_underline_is_not_an_unsupported_error
uline_paints_a_rule_under_the_argument uline_with_ulem_is_not_an_unsupported_error
xcolor_fixtures_match_pdflatex
$ grep -c 'adapter.rs:1308' branch.log -> 13
— the known stale vendor/compiler pin, not this PR's. (Counted in debug
deliberately: these are debug_asserts and a --release run would have shown a
misleading green.)
Targeted, on the branch:
$ 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
2. The fix genuinely fails on the base
I copied this branch's tests/vmode_boundary_skips.rs into the #722 worktree unchanged
and ran it against #722's source:
$ cargo test --test zz_review_vmode728 # 728's tests, 722's code
test an_abstract_shares_one_addvspace_with_the_environment_on_either_side ... FAILED
test the_boundary_error_does_not_accumulate_across_six_environments ... FAILED
test two_adjacent_paragraph_shape_environments_step_by_topsep_plus_partopsep ... FAILED
test result: FAILED. 4 passed; 3 failed
panicked at tests/zz_review_vmode728.rs:201:5:
10pt itemize -> abstract (adjacent): bravo: 176.608 bp, pdflatex 171.303 bp (+5.305)
+5.305 is the exact 10 pt figure in the PR body. The other two failures are the
verbatim cases the PR added to pre-existing tests — right, since verbatim is not in
TRIVLIST_ENVS on the base (adapter.rs:5004, 6 entries -> 9).
3. The two-column abstract — measured independently, and it is NOT regressed on #722
I rendered six abstract shapes on both revisions and compared every word's x and
baseline (scratch probe, deleted afterwards):
| probe | #722 base | #728 branch |
|---|---|---|
twocolumn + \maketitle + abstract |
identical | identical |
twocolumn, \end{itemize} -> abstract |
identical | identical |
twocolumn, \end{center} -> abstract |
identical | identical |
twocolumn, \end{abstract} -> itemize |
identical | identical |
one-column, \end{itemize} -> abstract |
body 176.608 | body 171.303 |
one-column, \end{abstract} -> itemize |
identical | identical |
Literal, for the two rows that matter:
722 TC 4-twocol-end-then-itemize n=9 :: Abstract@72.000/134.765 Abstract@72.000/156.585 body@113.318/156.585 … •@86.945/178.503 two@96.907/178.503 Tail.@81.963/200.421
728 TC 4-twocol-end-then-itemize n=9 :: Abstract@72.000/134.765 Abstract@72.000/156.585 body@113.318/156.585 … •@86.945/178.503 two@96.907/178.503 Tail.@81.963/200.421
722 TC 5-onecol-after-itemize … Abstract@172.498/176.608 body@210.710/176.608 … after.@222.795/194.540
728 TC 5-onecol-after-itemize … Abstract@172.498/171.303 body@210.710/171.303 … after.@222.795/189.235
So on #722 the two-column \end{abstract} sets nine words in the right places — it does
not expand to nothing, and there is nothing for this PR to have fixed there. The only
behavioural change is the one-column \end{itemize}\begin{abstract} shift of exactly
5.305 bp, which is the one the PR describes.
This matches what the PR says of itself — abstractenv.rs:276-282 ("measured it changes
nothing there … every two-column probe comes out byte-identical with and without this")
and the "Not done" bullet ("base and branch print byte-identical baselines for all nine
two-column probes"). The PR's own account of the two-column branch is accurate; the
claim I was asked to check was not a claim of this PR. Anyone carrying that
description forward should drop it.
Reading the change
take_lead (abstractenv.rs:269-320) is the right shape: the compiler hangs the
incoming skip on the block that was first, and inserting the head in front of it makes
the head that block, so the skip has to travel with the position. It moves all six
fields (eject_before, vspace_before, addvspace_before, addvspace_flex,
vspace_flex, endlist_adjust) rather than the one that happened to be wrong, and the
let … else { return } makes it a no-op for any non-Paragraph pair. Applying it to
the two-column branch on a positional argument, with the measurement recorded as showing
no change, is documented honestly at :276-282.
The \end{abstract}\begin{thm} size-dependence note is the kind of thing a 10 pt-only
sweep would have got wrong, and it is pinned as its own constant rather than folded into
a rule.
Verdict
VERIFIED — the line-by-line diff is exactly one added line, the new test fails on
the base with the stated figure, and the two-column branch is byte-identical across the
pair as the PR states.
Nothing was edited, pushed or merged; both scratch probe files deleted, both worktrees
clean.
— independently verified by daniel-parent's review lane
…#728 follow-up) What changed: flash-tex#728 left four things explicitly unmeasured. All four are measured now, over 1482 further probe documents against pdflatex, and nothing was added to TRIVLIST_ENVS for looking like a \trivlist. * `lstlisting` (listings) diverged twice and is *not* a \trivlist: `\lst@Init` opens no list. What it has is a `\par` and a `\vspace` at each end, and both were read as nothing. `\end{lstlisting}\begin{<trivlist>}` dropped `\partopsep` (-1.993/-2.989/-2.989 bp at 10/11/12 pt) because `\lst@DeInit`'s `\par` leaves vertical mode as `\@endparenv`'s does — a new `VMODE_END_ENVS`, deliberately kept apart from TRIVLIST_ENVS, since `\end{lstlisting}\begin{thm}` was right all along. `\end{<list>}\begin{lstlisting}` lost the whole closing `\@topsepadd` (-9.963/-11.955/-12.951) because `listings` zeroed the block's `addvspace_before` along with the `flushleft` lowering, although `\lst@Init`'s skip is a `\vspace` that adds to it rather than competing. The same after `flushleft` and `verbatim`, where the pair reads as one `ParaStyle` run and the closing skip is never materialised at all. * `Verbatim` (fancyvrb) and `alltt` are unimplemented and are left alone. The engine says so itself ("packages fancyvrb are recognised but not implemented"); measured, six `alltt` blocks land on one baseline (-21.917 bp by the second, -109.589 by the sixth at 10 pt). There is no \trivlist there to give a boundary skip to, so no test pins a number for them. * `report` and `book` measure exactly like `article` over the whole 8x8 boundary matrix at all three sizes, `lstlisting` included; `\@listI` does not differ by class. `book` differs only in its first baseline. The two class exceptions are outside a boundary and already declared: book.cls has no `abstract`, and `report`'s default `titlepage` branch sets one on a page of its own (head 317.407 bp, body 339.325, following material on the next page), which `abstractenv::Branch::TitlePage` does not set. * No boundary in this scope is size-dependent, and not by luck: both listings skips are `\vspace`s, so nothing competes for a class option to flip. Forcing `belowskip` to 4, 9 and 20 pt still measures a plain sum at all three sizes. The two-column `abstract` flash-tex#728 filed is fixed rather than filed again. It was one line of flash-tex#728's own argument: `\if@twocolumn`'s head is a `Block::Heading`, which has no `addvspace_before`, so `take_lead` fell out of its `let else` and left the list's `\@topsepadd` below the head to fire there (+3.985/+4.483/ +4.981 bp). `\@startsection`'s negative before-skip has already spent it above the head — pdflatex puts the head the same distance below an `itemize`, a `center`, a `verbatim`, a theorem and a plain paragraph — so it is dropped, with a real `\section*{Abstract}` in the same position as the control. The same sweep caught a regression flash-tex#728 introduced: `abstract` went into TRIVLIST_ENVS unconditionally, but article.cls 386 closes the environment with `\if@twocolumn\else\endquotation\fi`, so a two-column `\end{abstract}` expands to nothing. Every two-column `\end{abstract}\begin{<trivlist>}` was one `\partopsep` long (1.992/2.989/2.988 bp) against flash-tex#722, which was right. Whether that `\end` is an `\endtrivlist` is now a class-option question (`abstractenv::end_is_endtrivlist`), not a name lookup. What was run: cargo test --test vmode_boundary_skips test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 8.55s full crate --no-fail-fast, branch and base (a12ec1d) built identically, `test <name> ... <result>` lines diffed rather than totals: 497 lines on base, 501 on branch; 0 lines changed, 4 added, all ok: test a_lstlisting_boundary_is_the_neighbour_skip_plus_listings_own|ok test a_two_column_abstract_is_a_section_head_and_its_end_is_not_a_trivlist|ok test report_and_book_share_the_class_boundary_skips|ok test the_listings_skips_add_and_never_compete|ok 13 failures on both, all panicking at adapter.rs:1308 (stale vendor/compiler pin). every glyph of all 22 renderable fixtures under fixtures/real-world/ (HW1 and HW2 included), base vs branch: 15567 lines, 0 differences. listings-manual is the 23rd and panics at adapter.rs:1308 on both. probe sweeps against /Library/TeX/texbin/pdflatex with PyMuPDF glyph origins, 0.5 bp gate: 531 package documents, 891 class documents, 60 two-column documents; every remaining divergence involves only `alltt` or `Verbatim`, or `report`'s titlepage `abstract`. Next step: File report's `titlepage` abstract (204.560/205.624/209.875 bp plus a lost page break) and the `alltt`/`fancyvrb` gap as their own issues; neither is a boundary skip. Implementation-Agent: claude-opus-5 subagent of daniel-parent Commit-Executor: daniel-parent subagent Claude-Session: https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz
What
#722 closed the
\trivlistboundary forcenter,flushleft,flushright,quote,quotation,verseand every\newtheorem/proof, and left twogaps open on purpose:
verbatimandabstractare\trivlist-derived too, but were nevermeasured, so they were deliberately not added to
TRIVLIST_ENVS;Both are now measured, over 918 probe documents against pdflatex (pairs in
both directions, with and without a blank line, six-deep chains, solo and
paragraph controls, at 10 pt, 11 pt and 12 pt). Measurement, not
pattern-matching: three of the four things a "they're all trivlists" guess
would have predicted were already right, and the two real bugs have different
causes.
verbatimdiverged, but only where the pipeline reads the pair as oneParaStylerun.\@verbatimis\trivlist \item\relax ...and\endverbatimis\endtrivlist(latex.ltx), so\end{verbatim}leavesvertical mode and the next
\begintakes\partopsep.verbatim/verbatimand
verbatim/flushleftwere short by exactly that: -1.992 bp at 10 pt,-2.989 bp at 11 pt and 12 pt. It accumulates — six
verbatims in a rowdrifted 0, -1.992, -3.985, -5.978, -7.970, -9.963 bp at 10 pt.
verbatimagainstcenter,quote,quotation,verse,flushright, atheorem or any of the three lists was already correct in both directions.
abstractdiverged on both sides, for two different reasons.\end{abstract}is\endquotation->\endlist->\endtrivlist, so it isthe same boundary, and what followed it was short by one
\partopsep(-1.992 / -2.989 / -0.996 bp at 10/11/12 pt). The other direction is not
a
TRIVLIST_ENVSproblem at all: the pipeline builds the\small\abstractnamehead as a block inserted in front of the body the compilerproduced, and the boundary skip the compiler had hung on that body stayed
there and fired a second time below the head.
\end{itemize}\begin{abstract}came out +5.305 / +5.729 / +6.273 bp long, while
\end{center}\begin{abstract}was already right (acenter's closing skiprides on its own
env_close, not on the next block).take_leadmoves thatleading skip to the head with the position it belongs to.
No boundary diverged only at 11 pt or 12 pt, so the size sweep found no
third bug — but it did find that one boundary 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 but26.401 bp at 12 pt, because the
abstract's\@topsepaddwas 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 of thetwo
\addvspaces wins changes with the class option. That is pinned as itsown constant.
Why
The same
\addvspacerule #706 and #712 found reaches every\trivlist, and#722 said so but only measured the environments it had probes for. A
verbatimblock between two paragraphs of a listing-heavy document, or anabstractafter a list, is not exotic; the errors accumulate down the pageand move page breaks.
Pipeline-only, as #706/#712/#722 were: nothing under
vendor/changed, nore-pin.
Overlap check
GH-TRIVLIST-RESTheld bydaniel-parent(coord.py claimreturnedCLAIMED).gh pr list --state open --search topsep|verbatim|abstract: render-pipeline: two adjacent lists share one \addvspace, not two (#706) #712 and render-pipeline: every \trivlist boundary shares one \addvspace, not two (#712 follow-up) #722are this stack's own parents (this branch is based on render-pipeline: every \trivlist boundary shares one \addvspace, not two (#712 follow-up) #722's head); render-pipeline: a verbatim body inside a list is a trivlist inside that list (14/17) #268
(
verbatim-trivlist-in-list, DRAFT) is about averbatimbody's geometryinside a list, not about boundary skips, and touches neither
TRIVLIST_ENVSnorabstractenv.rs. No other open PR or claim touchescrates/render-pipeline/src/adapter.rsTRIVLIST_ENVS,crates/render-pipeline/src/abstractenv.rsortests/vmode_boundary_skips.rs.Test results
Diffing every
test <name> ... <result>line between the two runs givesexactly one line — the added
an_abstract_shares_one_addvspace_with_the_environment_on_either_side ... ok.No other test's result changed in either direction, so "0 new failures" is a
line-by-line fact rather than a count that happens to match. The same 13
failures on both sides are the known
adapter.rs:1308vendor/compilerpin(
every_line_is_where_pdflatex_put_it, threeletter_class_geometry,the_raggedleft_group_closes_no_trivlist,shared_colorbox_path_draws_border_with_content_inside, twouline, foursout/underline,xcolor_fixtures_match_pdflatex).hw2_sets_three_pages_with_the_reference_breaks ... okon both.Oracle: MacTeX 2026 pdfTeX 1.40, T1 Latin Modern, PyMuPDF glyph origins, 918
probe documents at the 10 pt / 11 pt / 12 pt
articlebase sizes (everyordered pair of 9 shapes x 12 partners, with and without a blank line,
six-deep chains, solo/paragraph/blank-line controls), plus nine
twocolumnprobes. pdflatex is an oracle only and never runs in the product path.
Not done
\begin{abstract}on the line directly after body text, with no blankline, is not recognised at all — measured, and left alone. The compiler
does not break the paragraph there, so it reports one text run across the
\begin, the pipeline finds no block inside the body to restyle, and no\abstractnamehead is set; the body lands 32.553 / 36.115 / 42.744 bphigh, on the previous line. Two adjacent
abstracts fail the same way(the second is dropped). This is a compiler-side paragraph-splitting gap
rather than a boundary skip (
\begin{center}in the same position doesbreak the paragraph), and fixing it means a change under
vendor/plus are-pin, which this line of work has stayed out of. It is the only
divergence left in the 918-document sweep and is documented at the top of
tests/vmode_boundary_skips.rs.lstlisting,Verbatim(fancyvrb) andallttare\trivlist-derivedtoo and are not added here: they were not measured, which is exactly
the reason render-pipeline: every \trivlist boundary shares one \addvspace, not two (#712 follow-up) #722 gave for leaving
verbatimout.twocolumnabstractafter a list sets its body 3.985 / 4.483 /4.981 bp low at 10/11/12 pt — measured, and left alone because it is
untouched by this PR: base and branch print byte-identical baselines for
all nine two-column probes. The
\abstractnamehead is exact, and thecenter-before and standalone cases are exact. That branch is a\section*and ordinary paragraphs rather than aquotation, so it is adifferent shape, not a
\trivlistboundary.articleclass was swept.report/bookshare\@listIbuthave their own
abstract, and were not measured.🤖 Generated with Claude Code
https://claude.ai/code/session_012c9XLkHjePPGBuarrmE2mz