DOCUMENTATION / UPSTREAM-CONSUMERS

Validate pinned upstream consumers

On this page

This harness renders upstream-authored inputs with the installed Vega and Mermaid development dependencies, then overlays the public annotation package. It proves compatibility with these particular inputs and renderer versions. It does not claim that Vega, Mermaid, or their websites adopted this library.

Reproduce the offline proof

From a clean checkout, install dependencies and the requested Playwright browser, then run the packed-consumer proof:

npm ci
npx playwright install chromium
npm run test:upstream -- --browser chromium --output-dir browser-evidence/upstream

The verifier uses the repository's Playwright dependency directly. No global browser CLI, private checkout, or upstream build script is required. It creates isolated browser contexts and closes them after each viewport check. Install firefox or webkit through the same Playwright command to test those engines.

--browser accepts chromium (default), firefox, or webkit. Both desktop (1360 × 1000) and narrow (390 × 844) run sequentially. Chromium and WebKit use touch-emulated mobile contexts and verify real touch pointer delivery. Firefox uses a narrow desktop context: the installed engine does not expose touch emulation, and its result is labeled narrow-desktop, not mobile-touch coverage. The recorded navigator.maxTouchPoints is observational: WebKit 27.2 on the CI host reported zero while delivering a native touch pointer to each fixture. Touch lanes therefore require real per-host pointerType="touch" events, not an advertised capability alone. Missing touch events fail even when the browser advertises a positive count. Browser calls have deadlines; fixture readiness has a 45-second limit. The source gate alone is inexpensive and needs no browser:

node scripts/verify-upstream-consumers.mjs --provenance-only

The default lane reads only checked-in snapshots. It packs the already-built package with lifecycle scripts disabled, extracts that tarball in the output directory, and resolves the fixture's @ponchia/annotations imports against its public export targets. Vite bundles both host renderers and the fixture. Browser requests outside the local preview server are blocked and fail the proof. A missing browser, missing input, failed render, failed request, console error, or assertion failure produces a nonzero exit; none becomes a green skip.

The default output is .tmp/upstream-consumers. Choose a fresh --output-dir outside .tmp when retaining independent runs; a package build can clean .tmp. results.json records the package tarball checksum, annotation Git revision, exact installed host versions, pinned source metadata, viewport profile, interactions, and measured geometry. A failed run writes passed: false and its error; a run that fails before provenance validation does not create browser evidence.

Inputs and attribution

The snapshots live in test/fixtures/upstream-consumers/inputs. The manifest records immutable source URLs, source-file SHA256, retained-input SHA256, extracted line ranges, expected mark/note counts, and adaptations.

Input Pinned upstream source Retained range License
Vega bar chart vega/vega, fdd9ab9d4faf Complete file, lines 1–96 BSD-3-Clause
Vega grouped bar chart vega/vega, fdd9ab9d4faf Complete file, lines 1–124 BSD-3-Clause
Mermaid client/services/storage flowchart mermaid-js/mermaid, 4e3a85e6d46a First “With the defaults” fence, content lines 116–134 MIT

The full relevant notices are retained in test/fixtures/upstream-consumers/licenses/vega-LICENSE (University of Washington Interactive Data Lab) and mermaid-LICENSE (Knut Sveidqvist). The source inputs were read through GitHub's contents API at these commits; no external repository code or build scripts were executed. Both Vega files are byte-for-byte copies. The Mermaid snapshot is the byte-for-byte fence content, without its Markdown fence delimiters. Its full source-document hash is recorded for future online review; the full document is not vendored, so offline checks validate the retained fence checksum rather than reconstructing the document hash.

When updating a snapshot, fetch the pinned file through gh api, inspect its authorship, content and license, then deliberately update the reviewed commit, URL, source-file hash, extracted range and retained-input hash together. The negative provenance tests reject a changed input or license until its expected checksum is updated; a floating main/develop URL also fails. Checksums detect unreviewed drift, not independent cryptographic proof of authorship.

Rendering adaptations and assertions

The host data, graph, encodings, dimensions, links and node text remain upstream authored. Vega uses its SVG renderer and a font-only configuration making axis and mark text 14px. Its original bar hover signal, red hover fill and value label are exercised in the browser. Mermaid uses the supported installed 11.x renderer defaults (Dagre, classic look and default theme), strict security, 16px fonts and startOnLoad: false. The develop document describes newer 12.x defaults; this proof does not test those defaults.

The fixture adds accessible SVG labels, nonsemantic target data attributes and an external overlay frame. All three hosts have three meaningful callouts: the bar chart's starting/highest/lowest amounts, the grouped chart's position-2 values across A/B/C, and the flowchart's Web app/API gateway/Orders DB nodes. prepareVegaSvgAnnotations and prepareMermaidAnnotations extract rendered targets and graphic/text obstacles. An additional obstacle protects the entire host graphic from note boxes. Solver obstacles include 4px clearance for note strokes. Independently retained, unexpanded protected-content rectangles are used for painted collision checks, while the package quality report checks the expanded solver obstacles. No actual painted overlap is permitted. Placement is automatic with explicit diagnostics: { candidates: 8 }, two refinement passes and a separate eight-candidate solver frontier per annotation. Candidate offsets include exact clearance distances derived from each target and the measured host boundary with a 12px gap. Coarse offsets alone initially left a 1px overlap with the protected chart frame; the proof rejected it. No manual note positions or approximate placement behavior are required.

Each viewport checks the complete host mark count, exactly three notes and connectors, successful anchor validation/alignment, and finite geometry. Independent client rectangles must agree with adapter targets within 0.25 CSS pixels. Note fill geometry is independently transformed from SVG getBBox and compared with resolved layout within the same tolerance. The browser client rectangle must match either the fill or its measured stroke envelope: Firefox includes stroke where Chromium excludes it. Collision and bounds checks use the conservative stroke envelope in every engine, rather than loosening the geometry tolerance or allowing painted overlap. Painted notes remain inside their frame, avoid each other, and avoid every protected host obstacle. Actual SVG text rectangles must fit inside note boxes, and effective host/note text must remain at least 13.5 CSS pixels. The verifier also checks zero package-reported invalid boxes, note overflow area, note overlap area and obstacle overlap area.

Connector obstacle/note crossings are recorded quantitatively in the quality metrics; they are not acceptance failures. Straight connectors to interior marks necessarily traverse some host space. This lane protects host content from notes, and does not promise collision-free connector routing.

gallery/ contains the complete bundled gallery, original-input disclosures, source attribution, adaptation lists and all overlays. Serve that directory with any local static HTTP server to inspect it; do not open it as a file: URL. Each host has a complete native-size PNG for each viewport. Mobile also has a viewport PNG showing the centered, horizontally scrolled host. The mobile lane verifies keyboard scrolling in all engines and emulated touch pointer delivery in Chromium/WebKit. It keeps document overflow contained in focusable graphic scrollers rather than shrinking desktop text. A complete graphic can require horizontal navigation on a phone; these screenshots do not claim a reflowed diagram or physical-device testing.

The fixture and its helpers remain verification code, outside the public package API. Node 22 CI runs the Chromium packed-consumer proof, and the experimental cross-browser lane runs Firefox and WebKit. Browser JSON and screenshots are retained as CI artifacts. No package version, publication policy, or supported public export changes are required.

The optional live public-website smoke is not implemented here. This evidence is a pinned offline upstream-input proof, not a live website annotation test.

Production consumer trial

A maintainer evaluating an actual application should record the installed package version, host library versions, annotation count, integration code and coordinate/measurement setup. Test changing data, viewport size, fonts and note text, then record any manual placement or custom glue required. Preserve a small reproducible example of each failure rather than adding an adapter API for a single host.

The trial is complete when another maintainer can reproduce it, verify readable notes and keyboard access in their real application, and explain whether the library reduced their integration work. Automated upstream examples are useful preparation, but do not replace that independent feedback or manual assistive- technology and physical-device checks.