Skip to content

docs(examples): stop the examples describing the releases they were written for - #491

Merged
DemchaAV merged 4 commits into
developfrom
fix/dated-example-prose
Aug 3, 2026
Merged

docs(examples): stop the examples describing the releases they were written for#491
DemchaAV merged 4 commits into
developfrom
fix/dated-example-prose

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Closes #490.

Why

Eight committed previews read as documents about 1.x. The drift gate cannot catch this — they render faithfully; it is the prose that dates them — which is why the issue was filed rather than automated.

preview said says
nested-list-showcase.pdf "v1.6 Phase A — Nested list ergonomics", "Nested lists landed in v1.6", "Migration guide v1.5 to v1.6", "Phase E.4 deferred to v1.7" the features themselves — a marker cascade, cells that compose a flow, a deferred hanging indent
canvas-layer-showcase.pdf "v1.6 Phase C", certificate headline "GraphCompose v1.6", "Issued for shipping the v1.6 expressive release…" "CanvasLayerNode — controlled free-canvas", and a certificate awarded for the page it is printed on
composed-table-cell-showcase.pdf "v1.6 Phase B", "the v1.5 line-only shape and the v1.6 composed shape" "Composed table cell content", "a line-only cell and a composed one"
rich-text-showcase.pdf links to docs/template-authoring.md and docs/v1.6-roadmap.md the preset cheatsheet and the extension guide
inline-highlight-chips.pdf "Run ./mvnw verify then tag v1.9.0 to publish graph-compose-emoji" "Run ./mvnw verify before pushing, and -Dtest=Name to narrow it to one class"
cover-letter.pdf, weekly-schedule.pdf "Composed with GraphCompose v1.5" "Composed with GraphCompose"
feature-catalog.pdf a canvas demo badged v1.8 beside charts and paint badged layout

The hyperlink example was worse than dated. Both URLs it renders had been deleted, so the example that demonstrates links shipped two broken ones. The replacements are in the tree.

Two the issue did not name. Its inventory listed three files; scanning all sixty-seven previews for a v1.x in rendered text — discarding measurements, scale factors and API arguments that look like versions — turned up composed-table-cell-showcase, rich-text-showcase, cover-letter, weekly-schedule and, on a second pass with the per-file cap removed, feature-catalog.

Left alone. inline-code-column-wrap.pdf still shows io.github.demchaav:graph-compose:1.9.0. The demo is about wrapping a long inline-code chip in a narrow column, and a Maven coordinate is the realistic thing to put there — the subject matter, not a stamp. #461 classified it that way and it still holds.

Found on the way: the gate was about to go red daily

pdf-chrome.pdf demonstrates the {date} header token, which HeaderFooterConfig resolved from LocalDate.now(). Its committed copy therefore differed from a fresh render on every day but the one it was committed on — this branch caught it because the date rolled over mid-session. On develop it would have failed the next morning on a tree nobody had touched, which is the fastest way to teach a team to ignore a guard.

The fix is a pinnable render date, not a special case in the comparator. Two attempts to solve it from the test side are in this branch's history and both left holes: the first dropped the file from the comparison; the second rebuilt "what a PDF means" by hand and missed the /Resources a watermark's opacity lives in, the nested bookmarks that are the point of that page, and the page boxes. Each patch would have added surface to maintain, to avoid one call to the clock.

-Dgraphcompose.renderDate=YYYY-MM-DD fixes what the token resolves to — the need SOURCE_DATE_EPOCH answers for archives. Unset, it is the clock, so nothing changes for anyone who has not asked; an unparseable value falls back to the clock rather than failing the render. The examples module pins it for both the tests and GenerateAllExamples, so the release renders the date the gate compares against, and the preview goes back through the ordinary byte comparison with ninety lines of hand-rolled comparator deleted.

Two things these previews had only been read for

Both had been true for six releases, and both render perfectly, so only reading caught them:

  • A preview naming a release the project has moved past — the subject of this branch, and a check it did by hand. Now a test, over the readable text of all sixty-seven: PDFs through a stripper, decks and the Word document through their packages, since checking only the PDFs would have left the six committed decks outside a guard whose name says every preview. It matches the v-prefixed form prose uses; a bare 1.9.0 is deliberately not matched, because a Maven coordinate is what the inline-code demo is about. Which majors count as stale is derived from the version being built, so it keeps working when today's previews are the dated ones.
  • An example rendering a link to a repository path that is not in the tree — how the hyperlink example came to ship two dead ones. The URLs point into a branch that moves, so a rename breaks them again in silence; resolving the path against the checkout costs nothing.

All three paths were mutated to confirm they bite: the pre-fix PDF reports [v1.5, v1.6, v1.7], a deck with a v1.6 injected into a text run reports twin-output.pptx [v1.6], and a redirected link reports the path.

Tests

examples 73 tests, qa 692 and core 426, green locally. Eight previews re-rendered — by name, because the gate asked for them.

Check Result
every committed preview matches what the catalogue renders passes, pdf-chrome.pdf through the same comparison as the rest
the {date} token: clock by default, pinned when asked, clock again on a bad value passes
no committed preview names a release the project has left behind passes; fails on the pre-fix preview
every repository link an example renders resolves to a file in the tree passes; fails on a redirected path

…ritten for

Eight committed previews read as documents about 1.x. Three framed a
current feature as "v1.6 Phase A/B/C" — a plan for a release that shipped,
on the pages demonstrating nested lists, composed cells and the free
canvas. One told the reader to tag v1.9.0 to publish a module that has been
on Central since. Two signed off "Composed with GraphCompose v1.5", which
dates itself again at every release, so the number is gone rather than
moved. One badged a canvas-placement demo "v1.8" beside badges reading
"charts" and "paint", where the version said nothing the other two did not
say better. And the certificate on the free-canvas page was awarded for
shipping v1.6; it is awarded for the page it is printed on.

The hyperlink example was worse than dated. Both URLs it renders — a
template-authoring page and a v1.6 roadmap — no longer exist, so the
example that demonstrates links shipped two broken ones. They point at the
preset cheatsheet and the extension guide, and both files are in the tree.

Left alone: the inline-code demo still shows a Maven coordinate with a
version in it, because a coordinate is what the demo is about — the subject
matter, not a stamp.

The eight previews are re-rendered, which is what the drift gate asked for
by name.
…g it

Leaving pdf-chrome.pdf out of the comparison absorbed eight characters and
gave up everything else: the page demonstrates a watermark behind the
content, an information dictionary, a header, a footer and bookmarks, and
none of it was being checked. That is a larger hole than the one it closed,
and a green build proved nothing about the one file it stopped reading.

The date is inside a compressed stream, so masking bytes was never
available — it is decompressed instead. That one file is compared by what it
draws and declares: page count, each page's operators with any ISO date
replaced, the metadata it sets, and the bookmark titles with the pages they
land on. Everything the example exists to show is back under the guard, and
what changes by itself is not. The workaround goes when the render date can
be pinned the way both fixed backends already accept a deterministic instant.

Two things these previews had only ever been read for are now read by a
test. A preview naming a release the project has moved past — the whole
subject of this branch, and a check the branch itself did by hand. And an
example rendering a link to a repository path that is not in the tree, which
is how the hyperlink example came to ship two dead ones: the URLs point into
a branch that moves, so a rename breaks them again in silence. Both were
mutated to confirm they fail: the pre-fix preview reports [v1.5, v1.6, v1.7]
and a redirected link reports the path.
The token read the clock with no way to say otherwise, so any document
using it was a different file every morning. The example demonstrating it
could not be held to its committed preview at all, and two attempts to work
around that from the test side both left holes: the first dropped the file
from the comparison, the second rebuilt "what a PDF means" by hand and
missed the resources a watermark's opacity lives in, the nested bookmarks
that are the point of that page, and the page boxes. Each patch would have
added surface to maintain, to avoid one call to LocalDate.now().

-Dgraphcompose.renderDate=YYYY-MM-DD fixes what the token resolves to — the
need SOURCE_DATE_EPOCH answers for archives. Unset, it is the clock, so
nothing changes for anyone who has not asked. A value that is not a date
falls back to the clock rather than failing the render: a typo in a build
flag should not stop a document being produced, and the drift it causes
surfaces where drift is checked.

The examples module pins it for both the tests and GenerateAllExamples, so
the release renders the same date the gate compares against, and that
preview goes back through the ordinary byte comparison with the hand-rolled
one deleted.

The content guard also stopped promising more than it checked. It read only
the PDFs while its name said every preview, leaving the six committed decks
— the most-linked of them — outside it; decks and Word documents are read
through their packages now. And which majors count as stale is derived from
the version being built rather than written down, so it still works when
today's previews are the dated ones.
The property is global. Clearing it in teardown removes what the build set
— the examples module pins a date so its previews are reproducible — and
whichever test ran first would take it away from everything after, with the
failure landing somewhere that has nothing to do with the cause.
@DemchaAV
DemchaAV merged commit 9a07574 into develop Aug 3, 2026
12 checks passed
@DemchaAV
DemchaAV deleted the fix/dated-example-prose branch August 3, 2026 08:00
DemchaAV added a commit that referenced this pull request Aug 3, 2026
Two examples sat under "🗄️ Legacy — pre-rebuild examples kept for downstream
callers still on V1; do not start new code here", with a link to a V1 → V2
migration path. There is no V1. That surface was removed in 2.0 —
docs/templates/which-template-system.md says so in its second sentence —
both examples compile against the current DSL, and three hundred lines
below the same file calls one of them a "useful starting point". The
category is renamed to what those examples actually are: documents
assembled from primitives, with no template behind them.

The run instructions led with GenerateAllExamples, which empties the output
directory and regenerates roughly a hundred documents. A reader following
the page top to bottom paid for the whole catalogue before seeing a single
example. Single-example first now, pointing at the Start-here table for
which one to pick; the batch entry point sits below it, labelled as the way
the committed previews and the showcase site are refreshed.

Also removes the release labels the #491 sweep left behind — "v1.5 feature
showcases", "v1.8 native vector charts", "the v1.9 book primitives",
"byte-identical to v1.4" — and, in the recipe index, a 1.x migration guide
that is still reachable from the documentation index's historical section.

./mvnw -B -ntp clean verify — BUILD SUCCESS, 692 tests in the closing
module.
DemchaAV added a commit that referenced this pull request Aug 3, 2026
Two examples sat under "🗄️ Legacy — pre-rebuild examples kept for downstream
callers still on V1; do not start new code here", with a link to a V1 → V2
migration path. There is no V1. That surface was removed in 2.0 —
docs/templates/which-template-system.md says so in its second sentence —
both examples compile against the current DSL, and three hundred lines
below the same file calls one of them a "useful starting point". The
category is renamed to what those examples actually are: documents
assembled from primitives, with no template behind them.

The run instructions led with GenerateAllExamples, which empties the output
directory and regenerates roughly a hundred documents. A reader following
the page top to bottom paid for the whole catalogue before seeing a single
example. Single-example first now, pointing at the Start-here table for
which one to pick; the batch entry point sits below it, labelled as the way
the committed previews and the showcase site are refreshed.

Also removes the release labels the #491 sweep left behind — "v1.5 feature
showcases", "v1.8 native vector charts", "the v1.9 book primitives",
"byte-identical to v1.4" — and, in the recipe index, a 1.x migration guide
that is still reachable from the documentation index's historical section.

./mvnw -B -ntp clean verify — BUILD SUCCESS, 692 tests in the closing
module.
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.

1 participant