Skip to content

docs: put the contributor surfaces on the 2.x vocabulary - #476

Merged
DemchaAV merged 2 commits into
developfrom
docs/2x-vocabulary
Jul 31, 2026
Merged

docs: put the contributor surfaces on the 2.x vocabulary#476
DemchaAV merged 2 commits into
developfrom
docs/2x-vocabulary

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Why

A contributor following CONTRIBUTING.md writes code that does not compile.

Its "new built-in template" section routes authors to BusinessTheme, InvoiceTemplateV2 and ProposalTemplateV2; its engine-primitive section tells them to add a container-growth marker and Breakable to an Entity, with geometry in EntityBounds and propagation in ParentContainerUpdater. All seven types were removed in 2.0 — checked one by one against src/main, none survive. The linked ComputedPositionTest does not exist either.

The same drift runs through the release-facing surface. ROADMAP.md still described 2.1 as "in development on develop, building toward the 2.1.0 minor" and 2.0 as the current stable line, five days after v2.1.0 was tagged and published. docs/README.md listed five superseded 1.x minor-to-minor upgrade guides on its main path and did not link migration/v2.0.0-modules.md at all — the only migration guide that applies to anyone arriving today.

And the example catalogue is stated four times with four different numbers: examples/README.md says 63 twice, CONTRIBUTING.md says 54, the release runbook expects "26+ Generated: lines". GenerateAllExamples invokes 94.

What changed

Retired API. The two template-authoring paths collapse to the one that exists: the layered stack, every preset a final class with a create(BrandTheme) factory, reference implementations named. The engine-primitive section describes the real pipeline — a NodeDefinition that prepares and measures, pagination declared on the definition rather than by a marker, continuation through SplittableLeafCompiler, and container growth as a consequence of what children report during prepare rather than a separate signal. The "Keep the entity core thin" block is deleted outright; every bullet in it named an absent type.

PPTX backend location. CONTRIBUTING.md (repository map and package roots), SECURITY.md (in-scope list) and docs/architecture/overview.md (package roots) described the pptx module as a semantic exporter. Its primary backend is fixed-layout — document.backend.fixed.pptx, consuming the same resolved LayoutGraph as the PDF backend — alongside the older semantic manifest skeleton, and both are now named. The handler-registration rule gains its second half: a new fragment kind must register with PdfFixedLayoutBackend and PptxFixedLayoutBackend, or it renders in one output and silently vanishes from the other.

This is deliberately not a sweep. PptxSemanticBackend still exists and render-pptx/README.md, docs/architecture/package-map.md and render-pptx/pom.xml describe it correctly; only the places calling it the module's primary surface are touched.

Release surface — one source of truth. Four surfaces gave three answers: the README advertised v2.1.1 as latest stable behind a tag URL that 404s, the changelog carried v2.1.1 as Planned, ROADMAP.md named 2.1.0 as current stable, and the site metadata said 2.1.0. The README was the false one, and it was false by design: cut-release.ps1 did not rewrite the release-status block, so the post-release commit that would fix it is develop-only and never reaches main — the v1.6.9 lesson recorded at release-process.md:309. The mitigation was a pre-cut hand-edit enforced by a Step 0 gate demanding the block already name the version being cut, so develop had to be wrong for a whole cycle to leave main right after the tag.

The block is script-owned now. Step 1 promotes the in-development half to latest stable — link text and tag URL both — and opens the next patch line; Assert-ReleaseMetadata verifies it after the mutation; Step 0 checks only that the block still exists in the shape the rewrite matches, so a reflowed blockquote aborts loudly instead of being skipped in silence. The maintainer owns the prose, not the version tokens. Pre-release state now reads Latest stable: v2.1.0 · In development: v2.1.1, and all four surfaces agree.

ROADMAP.md promotes 2.1 to current stable, demotes 2.0 to history, and points ## Now at what follows. docs/README.md leads with the guides that apply and folds the historical ones behind a <details>. SECURITY.md's supported-versions table jumped from 2.1.x to 1.9.x, leaving 2.0.x uncovered — a regression this branch introduced when it added the 1.9.x row, now fixed.

Templates and routing. bug_report.md is rewritten: the reproduction now uses try-with-resources and calls buildPdf() — as shipped, a repro pasted from the template rendered nothing — and ## Environment asks for the output backend, the modules on the classpath and the font source rather than a hardcoded PDFBox: 3.0.7, with a new ## Generated artifact section accepting a layoutSnapshot(). feature_request.md swaps BusinessTheme for BrandTheme and lists each anchor with its package (all verified present). pull_request_template.md gets the lanes the repository actually has and stops requiring a hand-updated gallery count. A new ISSUE_TEMPLATE/config.yml routes usage questions to Discussions, which are enabled and were not linked from anywhere.

Counts removed, not synchronised. examples/README.md, CONTRIBUTING.md and the release runbook. On the showcase page the first pass swapped 50+ for 80+, which only moves the problem to the next release — and left numberOfItems: 51 in the JSON-LD beside it and 50+ generated PDFs in the visible heading. All of them are gone: the page loads its catalogue from examples.json and can describe what it renders without claiming how many. A number in prose has no owner and no guard.

Runbook. One gate grepped README.md for [0-9]+ green tests — the README makes no such claim, so it always passed. Another compared examples/README.md gallery rows against *Example.java files: 48 against 100, already failing. Three items pointed at docs/migration-v1-N-to-v1-M.md, a path that moved to docs/migration/. The gallery gate becomes a ShowcaseMetadata coverage check, and a new item covers ROADMAP.md.

README structure. The comparison block moves below ## Architecture — same file, no discovery lost — so it stops sitting between the first working example and the next step. ## What's new in 2.0 compresses from thirteen lines to its two links. The documentation catalogue collapses from four sub-lists to four routes, gaining ROADMAP.md and SUPPORT.md, which the landing page never linked. 372 → 362 lines.

Three places fixed beyond the original scope, because #474 made them stale an hour before this branch: CONTRIBUTING.md:32 listed the pre-#474 guard names with no -pl scope, :73 claimed a docs-only PR "runs the guards only", and release-process.md:36 still warned that PackageMapGuardTest scans the gitignored docs/private/ and can fail a local run CI cannot reproduce — the exclusion #474 added is exactly what stopped that being true.

The README API table sent anyone adding a visual primitive to PdfFragmentRenderHandler alone, while CONTRIBUTING.md now requires registering with both fixed-layout backends. PptxFragmentRenderHandler exists; the row names both.

Verification

./mvnw -B -ntp clean verify -pl :graph-compose-core,:graph-compose-render-pdf,:graph-compose-render-docx,:graph-compose-render-pptx,:graph-compose-templates,:graph-compose-testing,:graph-compose,:graph-compose-bundle,:graph-compose-qa,:graph-compose-coverage -am

BUILD SUCCESS, 13/13 modules, 2:01, zero failures.

Claims were checked rather than assumed:

Claim How
Seven named types are gone grep for each declaration across every src/main — all absent
ComputedPositionTest is a dead link find — absent; repointed at LayoutInsetsTest
Three "Planned for v1.6" rows shipped CanvasLayerNode, ListBuilder.addItem(String, …), DocumentTableCell.node(DocumentNode) all present
The real example count 94 generate() invocations, 100 *Example.java files, 48 gallery rows
Every anchor a feature-request author is sent to each type located in src/main
The qa guard command in CONTRIBUTING.md run: 12 + 4 tests, BUILD SUCCESS
Links and anchors every relative link across the 16 files, and every #anchor in the restructured README, resolves
The release-status rewrite run against the real README: v2.1.0v2.1.1 in link text and tag URL, in-development v2.1.1v2.1.2
cut-release.ps1 parses clean (PowerShell AST, 4473 tokens)
JSON-LD after removing numberOfItems still parses
All four version surfaces README 2.1.0/2.1.1, CHANGELOG v2.1.1 — Planned, ROADMAP Current stable — 2.1, site softwareVersion 2.1.0, install pin 2.1.0

The documented qa command was run on a warm ~/.m2, which is exactly its trap: a standalone -f qa/pom.xml resolves its graph-compose-* dependencies from the local repository rather than the reactor, so without a prior install it quietly tests the last artifacts you installed instead of your working tree. That precondition is now part of the instruction.

One decision to confirm

ISSUE_TEMPLATE/config.yml sets blank_issues_enabled: false. That is what forces the routing — every report goes through a template or a contact link — but it removes the blank-issue escape hatch, and it is the only behavioural change here rather than a textual one. Happy to flip it to true and keep just the contact links.

Not in scope

docs/contributing/implementation-guide.md still describes the removed execution layer and carries dead source links. Rewriting it is its own change; this PR demotes it from "read these files first" to background reading and adds package-map.md in its place.

Nothing here is machine-checked: no guard scans SECURITY.md, SUPPORT.md, ROADMAP.md or .github/**, and none of the retired symbols are on a forbidden-token list, so every correction in this PR can silently return. Closing that is the next change in this series.

DemchaAV added 2 commits July 31, 2026 08:36
Several documents still described an architecture that shipped out of the
repository in 2.0, and a contributor following them wrote code that does not
compile.

CONTRIBUTING routed template authors to BusinessTheme, InvoiceTemplateV2 and
ProposalTemplateV2, and its engine-primitive section described entities,
container-growth markers and Breakable. None of those seven types exist in
src/main. Both sections now describe what is there: the layered preset stack
with create(BrandTheme), and the NodeDefinition pipeline where pagination is
declared by the definition and a splittable node compiles through
SplittableLeafCompiler. A dead link to ComputedPositionTest points at a test
that exists.

CONTRIBUTING, SECURITY and the architecture overview called the pptx module a
semantic exporter. Its primary backend is fixed-layout, in
document.backend.fixed.pptx, alongside the older semantic manifest — and a new
fragment kind has to register a handler with both fixed-layout backends, or it
renders in one output and silently vanishes from the other. The semantic
wording is left in place everywhere it is still accurate.

ROADMAP described 2.1 as in development and 2.0 as current stable, four days
after 2.1.0 shipped. The README release-status block described 2.1.1 with
2.1.0's headline. docs/README listed five superseded 1.x upgrade guides on the
main path and omitted the 2.0 migration guide entirely.

The bug-report template asked for a v1.6-era version and offered a reproduction
with no try-with-resources and no render call, so a repro pasted from it
produced nothing. It now asks for the backend, the classpath, the font source
and the generated artifact or layout snapshot. The feature-request template
pointed at BusinessTheme; the pull-request template offered a lane that does not
exist and required updating a count by hand. A new issue-template config routes
usage questions to Discussions.

Four places stated four different example totals — 63, 63, 54 and "26+" — where
the runner invokes 94. The numbers are removed rather than synchronised; they
have drifted every release since June.

The release runbook grepped the README for a test-count claim the README does
not make, so that gate always passed; it compared the gallery row count against
the example file count, two numbers long diverged; and three items pointed at a
migration path that moved. The gallery check is now a ShowcaseMetadata coverage
check, and a new item covers ROADMAP.

canonical-legacy-parity.md is refreshed rather than archived: eight live
documents link it, and its three "Planned for v1.6" rows had all shipped.

In the README, the comparison block moves below Architecture so it stops
separating the first example from the next step, What's new in 2.0 compresses to
its links, and the documentation catalogue collapses to four routes.
The README advertised v2.1.1 as latest stable behind a release link that 404s,
while the changelog carried v2.1.1 as Planned, the roadmap named 2.1.0 as the
current stable line, and the showcase metadata said 2.1.0. Four surfaces, three
answers.

The false one was the README, and it was false on purpose. cut-release.ps1 did
not rewrite the release-status block, so the post-release commit that would fix
it lives on develop and never reaches main — the v1.6.9 lesson recorded in the
runbook. The mitigation was a pre-cut hand-edit, enforced by a Step 0 gate that
demanded the block already name the version being cut. To leave main correct
after the tag, develop had to be wrong for the whole cycle.

The block is script-owned now. Step 1 promotes the in-development half to latest
stable, rewriting both the link text and the tag URL, and opens the next patch
line; Assert-ReleaseMetadata verifies the result after the mutation. Step 0 no
longer demands a hand-edit — it checks the block still exists in the shape the
rewrite matches, so a reflowed blockquote aborts loudly instead of being skipped
in silence. What the maintainer owns is the prose, not the version tokens.

SECURITY.md's supported-versions table jumped from 2.1.x straight to 1.9.x,
leaving 2.0.x uncovered — a regression introduced when the 1.9.x row was added.

The showcase page still stated a count in three places while the JSON-LD beside
them declared numberOfItems: 51 and the visible heading said "50+ generated
PDFs". Replacing one number with another moves the problem to the next release,
so the counts are gone; the page loads its catalogue from examples.json and can
say what it renders without claiming how many.

The runbook still told the maintainer that PackageMapGuardTest scans the
gitignored docs/private/ and can fail a local run CI cannot reproduce. That
stopped being true when the exclusion landed; its guard list was also missing
CiGuardListGuardTest.

The README API table sent anyone adding a visual primitive to
PdfFragmentRenderHandler alone, while CONTRIBUTING now requires registering with
both fixed-layout backends — a handler registered with one renders in one output
and vanishes from the other.
@DemchaAV
DemchaAV merged commit 8320aea into develop Jul 31, 2026
12 checks passed
@DemchaAV
DemchaAV deleted the docs/2x-vocabulary branch July 31, 2026 17:21
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