Problem
FontMaterializationPlanBuilder::fromWebFontSources() merges every parsed CSS font-family into a google_fonts plan. It then emits one Google CSS2 request containing those families, even when only a subset came from a Google <link> or @import.
A three-route acceptance artifact with one declared Google family (Poppins) produced a request containing 23 unrelated system/custom tokens, including %2309152B, Consolas, Helvetica Neue, Wix-generated names, and Japanese メイリオ. Google returned HTTP 400, and downstream transactional materialization rolled back.
The source document metadata correctly retained only:
https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700;800&display=swap
The generated materialization request incorrectly included all parsed CSS usage.
Root cause
fromWebFontSources() combines provider-backed usage with fontUsageFromCssDeclarations() and inline-body usage, then passes that entire set to googleFonts(). CSS usage proves a desired family, not that Google hosts it.
Expected contract
- Google materialization requests contain only families proven by supported Google stylesheet links/imports.
- CSS-only system/custom families may remain typography roles or unresolved diagnostics, but are not synthesized into Google URLs.
- A mixed fixture proves the emitted URL keeps the declared Google family and excludes colors, system fonts, and custom-hosted names.
Acceptance evidence
The failure is deterministic: the malformed stylesheet response had 6,322 bytes under the 262,144-byte cap but returned a non-200 response, producing stylesheet_fetch_failed.
AI assistance
GPT-5.6-sol via OpenCode traced the compiled plan and materialization receipt, identified the provider-provenance conflation, and drafted this report. Chris Huber reviewed and remains responsible for the issue.
Problem
FontMaterializationPlanBuilder::fromWebFontSources()merges every parsed CSSfont-familyinto agoogle_fontsplan. It then emits one Google CSS2 request containing those families, even when only a subset came from a Google<link>or@import.A three-route acceptance artifact with one declared Google family (
Poppins) produced a request containing 23 unrelated system/custom tokens, including%2309152B,Consolas,Helvetica Neue, Wix-generated names, and Japaneseメイリオ. Google returned HTTP 400, and downstream transactional materialization rolled back.The source document metadata correctly retained only:
The generated materialization request incorrectly included all parsed CSS usage.
Root cause
fromWebFontSources()combines provider-backed usage withfontUsageFromCssDeclarations()and inline-body usage, then passes that entire set togoogleFonts(). CSS usage proves a desired family, not that Google hosts it.Expected contract
Acceptance evidence
The failure is deterministic: the malformed stylesheet response had 6,322 bytes under the 262,144-byte cap but returned a non-200 response, producing
stylesheet_fetch_failed.AI assistance
GPT-5.6-sol via OpenCode traced the compiled plan and materialization receipt, identified the provider-provenance conflation, and drafted this report. Chris Huber reviewed and remains responsible for the issue.