fix(lint): mention src: local() for system fonts in font_family_without_font_face#1859
Conversation
…ut_font_face Two independent post-release feedback reports of this rule hard-erroring on OS system fonts (Hiragino Sans, Microsoft YaHei) that have no downloadable file. Both asked for the same thing, in slightly different words: a documented way to satisfy the check for a font that's genuinely OS-bundled, not missing. That way already exists and already works — extractFontFaceFamilies only looks at the font-family declaration inside @font-face, never the src value, so `@font-face { font-family: 'X'; src: local('X'); }` already passes. One report found this themselves; the other didn't. The gap was discoverability: the fixHint only described bundling a real font file, so nobody would think to try `local()` unless they already knew about it. Considered and rejected a broader fix: adding CJK system-font names to the shared FONT_ALIAS_MAP (the mechanism that already exempts Latin system fonts like Segoe UI/Verdana by aliasing them to a bundled fallback font). That map has no CJK-equivalent bundled font to alias to (only Japanese has one, noto-sans-jp) — aliasing "Microsoft YaHei" (Simplified Chinese) to a Japanese font would silently swap in the wrong glyph shapes for shared Han characters, and would specifically break distributed/Lambda rendering (where system-font capture is disabled, per system_font_will_alias's own comment) by removing the warning that currently prompts a real fix. The local() message fix has none of that risk: it changes no detection logic, only points at an already-correct existing escape hatch. Tests: local() font-face no longer flags (proves the advice is accurate, not just documented); fixHint contains "local(". 308 lint tests pass.
james-russo-rames-d-jusso
left a comment
There was a problem hiding this comment.
Reviewed at 37186178dd (batch review, Group C lint quality; layering on Magi's own vetting).
Note: bot-authored (Magi via miguel-heygen); COMMENT-quality — stamp routing per protocol.
Summary — pure fixHint copy change on font_family_without_font_face, surfacing an already-supported escape hatch (@font-face { src: local(...) }). No detection-logic change.
Verified
- The claim that
@font-face { font-family: 'X'; src: local('X'); }already passes the check is correct:extractFontFaceFamilieslooks only at thefont-familydeclaration inside@font-face. Test 1 (thelocal()regression test) proves that end-to-end. - Test 2 asserts the
fixHintstring contains"local("— pins the wording so a future edit that drops the hint gets caught. Good regression fence. - The rejected alternative (aliasing CJK fonts into
FONT_ALIAS_MAP) is correctly rejected — the map's target font would default tonoto-sans-jp(Japanese) and silently swap Han glyph shapes for Simplified Chinese users, AND would remove thesystem_font_will_aliasdistributed-render warning that currently prompts the real fix. Diff avoids the wrong-looking-fix trap.
Nits
- 🟡 The hint says
src: local('Exact Font Name')— worth noting elsewhere thatlocal()unmatched-on-system falls through to the CSS fallback chain silently, so users who ship this on a machine that doesn't have Hiragino will still get a substituted font at render time. Not the lint's problem to warn about (that's the render-time system-font-capture story), just a downstream nuance.
— Rames D Jusso
jrusso1020
left a comment
There was a problem hiding this comment.
APPROVE — verified CI green (0 fail / 0 pending) + no open CR at this head. Non-author stamp clearing the review gate on the Magi self-initiated draft-pass batch, which James greenlit and RDJ batch-cleared: both security holds re-verified at R2 (#1866 chrome-shell reclaim-race closed via the reclaim-gate + mtime recheck; #1845 Windows npx shell-injection closed — no cmd.exe, node <npx-cli.js> with pure argv), zero drift on the other nine, all green.
Merge via Magi's normal path (no admin-merge). Ordering note: the skills-manifest triple-conflict on #1877 / #1862 / #1845 (all bump hyperframes-media.hash) needs sequential rebase + regen at merge time; the rest land in any order.
— Rames Jusso
Root-caused from two independent post-release feedback reports of
font_family_without_font_facehard-erroring on OS system fonts (Hiragino Sans, Microsoft YaHei) that have no downloadable file.What's actually going on
@font-face { font-family: 'X'; src: local('X'); }already satisfies the check —extractFontFaceFamiliesonly looks at thefont-familydeclaration inside@font-face, never thesrcvalue. One reporter found this workaround themselves; the gap is discoverability: thefixHintonly described bundling a real font file, so nobody would think to trylocal()unless they already knew about it.Fix
Mention the
local()pattern in thefixHint. No detection-logic change.What I considered and rejected
Adding CJK system-font names (Hiragino, Microsoft YaHei, etc.) to the shared
FONT_ALIAS_MAP— the mechanism that already exempts Latin system fonts (Segoe UI, Verdana, ...) by aliasing them to a bundled fallback. That map has no CJK-equivalent bundled font to alias to (only Japanese has one,noto-sans-jp). Aliasing "Microsoft YaHei" (Simplified Chinese) to a Japanese font would silently swap in the wrong glyph shapes for shared Han characters — and would specifically break distributed/Lambda rendering (where system-font capture is disabled, persystem_font_will_alias's own comment) by removing the warning that currently prompts a real fix. That's a plausible-looking fix that would have been actively wrong. Thelocal()message fix has none of that risk: zero detection-logic change, just surfaces an already-correct existing escape hatch.Tests
local()font-face no longer flags (proves the advice is accurate, not just documented);fixHintcontains"local(". Full lint suite (308 tests) passes.