# 字体授权与缺失资源降级 Type: grilling Status: resolved Labels: wayfinder:grilling Blocked by: 01, 02 ## Question 正式字体、图标、状态资源或装饰资源缺失、不可授权、加载失败、尺寸不合格或与部署环境不兼容时,系统如何处理?裁定 Web 字体的授权证据、可接受的回退字体、逐项资源的降级层级、用户可见提示、日志/诊断信息,以及何种缺口阻止发布、何种缺口允许带回退交付。 降级必须可见且不把临时资源误报为正式设计资产;不能因为单个资源失败而静默破坏整个驾驶舱。 ## 进度 - 已认领(`Status: claimed`);阻塞票 01/02 均 closed。票 03(token 槽位)、票 04/09(manifest 降级链)、票 05(位置符号)均已完成。 - deck 工具已按插件要求上报本票(带 `effortId=lanhu-cockpit-asset-replacement`)。 - 事实侧已自查(不向维护者提问可自得的事实): - `tokens.css` 现有 `--font`(`Microsoft YaHei UI`/`Microsoft YaHei`/`PingFang SC`/`Noto Sans SC`)与 `--num`(`Bahnschrift SemiBold`/`Bahnschrift`/`DIN Alternate`/`Segoe UI Semibold`)**都是系统字体栈,非 Web 字体**。 - 票 04/09 已锁 manifest 降级链(显式 fallback → 有限链 → 内置通用资源)、核心资源整包回滚、分环境诊断;票 05 已锁位置符号降级。**本票不重开这些机制**。 - 维护者指定字体目录 `E:\_Design\字体`,实测结论见下节。 ## 字体目录实测事实(本票自查,非推断) 对 `E:\_Design\字体` 做了完整取证(递归列举 + 字体内嵌元数据提取): - 目录结构:68 个 zip(合计 707.7 MB)+ `中文/`(65 个文件,515.8 MB)+ `英文/`(15 个文件,1.3 MB)。 - **授权文件:零命中**。递归搜索 `license|licence|readme|授权|许可|声明|OFL|copyright|商用` 无任何命中;`字体.zip` 的 82 个条目同样零命中。 - **确证开源(内嵌版权/许可文本可查)**: - `SourceHanSansSC-*` 与 `SourceHanSansCN-VF`:`2014-2021 Adobe, with Reserved Font Name 'Source'` → 思源黑体(OFL)。 - `SourceHanSerifCN-*`:`Copyright 2017 Adobe Systems Incorporated … Reserved Font Name 'Source'` → 思源宋体(OFL)。 - `CrimsonText-*`:`Copyright (c) 2010, Sebastian Kosch … with Reserved Font Name` → SIL OFL 开源西文。 - **明确保留所有权利(与「整目录免费可商用」矛盾)**:`Modernia-Regular`(`Copyright © 2019 … All rights reserved`)、`Furore`(`Copyright (c) 2009 … All rights reserved`)。 - **无许可文本(名字暗示免费但未确证)**:`SmileySans`(得意黑)、`PangMenZhengDao…MianFeiBan`、`【MianFei】CangJi…`、`ZQKfreefont`、`Versa`、`SendaDisplay-BECO` 等。 - **公认商用收费字库(高风险)**:`douyuFont`(斗鱼)、`PingFangLaiJiangHuFeiYangTi`、`JiYingHuiPianHuiSong`、`TaiWanQuanZiKuZhengKaiTi`、`UnBatang`、`GenShinGothic`、`AozoraMincho`、`SoukouMincho`、`DelagothicOne`、`HuXiaoBoNanShenTi`、`HongLeiXingShuJianTi`、`Mengshen-Handwritten` 等。 - 体积参考(二进制字节实测):思源黑体单字重约 15–16 MB(`SourceHanSansSC-Regular` **15.7 MB**、`SourceHanSansSC-Bold` **16.2 MB**);思源宋体 `SourceHanSerifCN-Regular` **10.7 MB**;西文 `CrimsonText-Regular` 仅 **0.1 MB**。中文全量内置的体积代价远高于西文。 **结论**:该目录是字体文件集合,**不是已核验的合规库**;「整目录免费可商用」的说法与实测不符(`Modernia`/`Furore` 明确保留所有权利)。 ## 第一轮裁定(已确认) - **Q1=B**:无书面授权证据**不得内置**字体文件;运行时回退到已批准的系统字体栈,并在缺口清单记为「设计字体未接入」,缺口可见但不阻断整批交付。 - **Q2=B**:授权证据需**书面/电子文件**(许可协议、采购凭证或权利人声明),明确覆盖 **Web 嵌入与商用范围**,注明字体名称与版本。补充裁定:**系统自带字体不属于可再分发字体**,只能作回退栈,不得打包进产物。 - **Q3=B**:数字字体与正文同规;若不可授权,回退必须选**度量兼容**(字宽/字高接近)的备选,避免大屏 KPI 数字换字后跳格。 - **Q4=B**:**仅三类缺口阻断发布**——① 核心资源组(品牌标识、点位/设备状态形状语义、状态色)不可用;② 视觉会**误导业务语义**(如状态色缺失致报警与正常无法区分);③ 法规/授权风险(无授权字体、无授权品牌素材)。其余缺口允许带回退交付并列入缺口清单。 - **Q5=B**:三层可见——① 运行时诊断(开发/测试可见语义 key 与失败类别);② 交付缺口清单(语义 key、缺口类型、回退结果、责任人);③ 生产界面只显示**用户可理解提示**,不暴露内部路径。 - **Q6=B**:临时资源**必须带临时标记**;验收**不得**以临时资源作为正式视觉通过;缺口清单必须列出仍未替换的临时项。 ## 第二轮裁定(已确认) - **Q7(维护者原话:尽量以现有情况为基准)+ Q11=A + Q15=A**:统一原则——**优先沿用现有渲染尺寸与既有实现**,只有素材在现有尺寸下确实不可辨时才做**最小调整**并记录偏差;该原则**同时适用于字体**,Web 字体属「可选优化」而非「必需修复」。这消除了票 05 遗留的「内层图标 10.8px 是否需调整」的处置口径。 - **Q8=A**:本票**只新增**字体授权裁定与缺口分级,**不重复定义**降级链、回滚或诊断字段(避免与票 04/09/05 形成两套说法)。 - **Q9=A**:字体目录采用**白名单制**;未入白名单者按 Q1 走回退,待逐项核验后再进白名单。 - **Q10=C**:**不引入任何商用字体**,只用开源白名单与系统字体栈。因此不存在「向设计公司索取商用字体授权凭证」的工作项。 - **Q12=A**:**严格白名单**——只放行本目录内**确证带开源许可文本**的字族:思源黑体 `SourceHanSans*`、思源宋体 `SourceHanSerif*`、`CrimsonText*`。其余(含名字暗示免费的得意黑 `SmileySans`、`ZQKfreefont`、`PangMenZhengDao…MianFeiBan`、`【MianFei】CangJi…`)**一律按无证据处理**;若要纳入,须先把上游 OFL 许可证文本归档进交付包,方可从「名字暗示」升级为「确证」。 - **Q13=A**:`--font` / `--num` 的**语义槽位不动**(票 03 已锁),本票只给出**可接入字族白名单**;是否启用由实现按观感决定。明确不强制用思源黑体替换现有系统栈(体积风险)。 - **Q14=B**:大体积中文字体必须**子集化**(仅收驾驶舱实际用字)或**限定字重数量**(如 Regular + Bold 两档),并在缺口清单记录被裁字符集风险。**子集字体必须保留系统字体回退链**——因为动态数据(设备名、点位名、事件文本)可能含子集外汉字,单独使用会出现豆腐块。 ## Answer **本票不重开既有降级机制,只锁定「字体授权」与「缺口分级」两件事;字体采用严格开源白名单 + 系统回退栈,任何未确证授权的字体一律不内置。** ### 字体授权 1. **授权门槛**:字体内置需书面/电子授权证据,明确覆盖 Web 嵌入与商用范围并注明名称与版本;**系统自带字体只能作回退栈、不得打包**。 2. **严格白名单(本目录内确证)**:思源黑体 `SourceHanSans*`、思源宋体 `SourceHanSerif*`、`CrimsonText*`。未入白名单者按无证据处理,走系统回退。 3. **不引入商用字体**;因此不存在商用字体授权索取工作项。 4. **槽位归属不变**:`--font` / `--num` 的语义槽位仍归票 03,本票只给可接入字族集合,不强制替换现有系统栈。 5. **交付约束**:中文字体必须子集化或限定字重档数,且**必须保留系统回退链**(动态数据可能含子集外汉字)。 6. **数字字体**:若不可授权,回退须**度量兼容**,避免大屏 KPI 数字跳格。 ### 缺口分级(阻断 / 允许带回退) - **阻断发布(三类)**:核心资源组不可用;视觉会误导业务语义;法规/授权风险。 - **允许带回退交付**:其余缺口,条件是①记录进缺口清单(语义 key、缺口类型、回退结果、责任人);②验收不得把临时资源当正式视觉通过;③临时资源必须带临时标记。 - **可见性三层**:运行时诊断(开发/测试)→ 交付缺口清单 → 生产仅显示用户可理解提示,不暴露内部路径。 ### 与既有裁定的关系 - **不重开**:降级链与 fallback 顺序归票 04/09;位置符号降级归票 05;token 槽位语义归票 03。 - **统一原则**:尺寸与字体一律「优先现状,仅在不可辨时最小调整并记录偏差」(Q7/Q11/Q15)。 ### 风险与边界 - **目录非合规库**:`E:\_Design\字体` 零授权文件且含明确保留所有权利的字库(`Modernia`/`Furore`)与多款公认商用收费字库;因此**不得以目录为单位放行**。 - **子集化风险**:子集外汉字会落到回退字体,可能出现同屏字形混排;实现需在走查中确认动态文本仍可读。 - **本票不声称**已接入任何 Web 字体、已子集化或已替换现有系统栈;这些属实现工作。 - 按 `AGENTS.md`,本轮未运行 build/dev/浏览器调试。 ## 真实状态与下一步 - 状态:**已完成并关闭**(`Status: resolved`)。Q1–Q15 全部有裁定,无遗留未决项。 - 交付物: 1. 本票 `Answer`(上述结论); 2. 规格子票[字体授权与缺失资源降级规格](11-font-and-fallback-spec.md)(`ready-for-agent`,已挂入同一张地图); 3. 交叉引用修正:既有[运行时资产 manifest 与版本策略规格](09-runtime-asset-manifest-spec.md)使用了「核心资源组」与 `核心标记` 字段但未定义成员,已加指针指向本票规格补全的定义(只加指针,不改其原口径)。 - **对抗式审查记录(2026-10-08)**:规格发布后对本次产出做了对抗式复核。 1. **抓到并修正 1 处事实错误**:曾把思源黑体体积写作 16.4 MB / 17.0 MB,二进制字节复核实为 **15.7 MB / 16.2 MB**(原数字取自目录列表中混入的其他条目)。已更正并复检无残留。 2. **抓到并补全 1 处真实缺口**:既有资产清单规格使用「核心资源组」概念却未定义成员,本票规格补全了成员定义并建立双向交叉引用,避免读过其中一个规格的人找不到定义。 3. **核实通过**:零授权文件断言(递归命中 0);`Modernia` / `Furore` 的 `All rights reserved` 原样命中;白名单文件均真实存在;能力边界表述未越界(3 处均明确「不声称判定授权合法性」);与票 03 槽位归属不冲突;未重复定义票 09 的降级链与回滚。 - 下一步:推进[设计稿差异与现有业务结构保护](07-design-diff-and-structure-boundary.md)(其阻塞票 02–06 均已关闭);实现工作由规格子票承接。 ## 缺口清单 执行批次归视觉的偏差与未替换临时项登记于此(唯一来源;语义 key、缺口类型、回退结果、责任人四列齐全)。 | 语义 key | 缺口类型 | 回退结果 | 责任人 | | --- | --- | --- | --- | | `icon.brand` | 已关闭:已替换为蓝湖正式切图(`nav/title-bg` 品牌标题底板,90×34@2x) | 正式切图,manifest `status: formal` | —(2026-10-12 批次 1 关闭) | | `icon.layers` | 已关闭:已替换为蓝湖正式切图(网格,15×15@2x) | 正式切图,`formal` | —(2026-10-12 批次 1 关闭) | | `icon.points` | 已关闭:已替换为蓝湖正式切图(水滴,16×15@2x) | 正式切图,`formal` | —(2026-10-12 批次 1 关闭) | | `icon.event` | 已关闭:已替换为蓝湖正式切图(警告三角,24×24@2x) | 正式切图,`formal` | —(2026-10-12 批次 1 关闭) | | `icon.resource` | 已关闭:已替换为蓝湖正式切图(火焰,15×15@2x) | 正式切图,`formal` | —(2026-10-12 批次 1 关闭) | | `icon.blank` | **设计稿未覆盖**:空面板占位图示在蓝湖稿中无对应物 | 维持现状:内联几何迁移的临时 SVG(manifest `status: temporary`)+ 标记「无设计稿依据」 | 维护者/设计方 | (2026-10 批次 1 执行时登记,见[执行-批次1:品牌/图标替换](14-exec-batch1-brand-icons.md)。) **2026-10 更新一(依据[票 19 盘点报告](research/19-lanhu-artboard-inventory.md))**:上表六条原记为「正式素材未交付(蓝湖盘点未完成)」。旧版盘点完成后事实修正为**「设计稿未覆盖」**——旧版蓝湖画板中品牌位无 logo 图形、四个功能图标在稿中为纯文字 chip,故不存在"待交付的正式切图"。 **2026-10-12 更新二(蓝湖已更新正式切图,批次 1 重做)**:蓝湖 9 个画板全部升版(v3/v4,更新时间 2026-10-12),AI 生成底图与全部位图填充被移除,**正式切图标记由 27 个增至 71 个**。其中五枚与驾驶舱语义 key 对应(品牌标题底板、网格、水滴、警告三角、火焰),已入库并登记 `formal`,对应缺口关闭。**「设计稿未覆盖」现仅剩 `icon.blank` 一条**。 **2026-10 更新三(批次 4 字体接入,票 17)**:字体白名单经维护者裁定扩展为六族(原三族 + 设计稿实际使用的 `Noto Sans SC` / `Rajdhani` / `Share Tech Mono`,均 OFL 且已归档上游许可证文本)。本批**实际嵌入**正文字族与数字/等宽字族(子集化,合计 446 KB)。下表新增字体相关条目: | 语义 key / 字族 | 缺口类型 | 回退结果 | 责任人 | | --- | --- | --- | --- | | `font.body.*`(Noto Sans SC Subset) | **已关闭**:设计稿正文(913 处)已接入 | 正式 Web 字体,`licenseId=ofl-noto-sans-sc` | —(2026-10 批次 4 关闭) | | `font.num.*`(Rajdhani / Share Tech Mono Subset) | **已关闭**:设计稿数字/等宽(163 / 134 处)已接入 | 正式 Web 字体,`licenseId=ofl-rajdhani` / `ofl-share-tech-mono` | —(2026-10 批次 4 关闭) | | 全部子集字体 | **子集外字符走回退**(预期行为,规格 11 Q14):子集只收驾驶舱静态用字 1435 字,后端动态文本(设备名 / 点位名 / 事件文本)中的生僻汉字不在子集内 | 落到 `--font` / `--num` 系统回退链(Microsoft YaHei / PingFang / Noto Sans SC);**需走查确认动态文本无豆腐块** | 维护者(走查) | | `--num` 数字字体 | **度量偏差(逐字差 > 0.05 em,共 16 项)**:Rajdhani 的 `'5' '7' '-' '(' ')'`(−0.06 ~ −0.17 em)与 `'%'`(+0.05);Share Tech Mono 的 `'1' '.' ':' '/' '(' ')' '%' '-'`(−0.15 ~ +0.31 em) | 数字**内部等宽性不劣于**原字体(Rajdhani 0.203 / Share Tech Mono 0.000 vs Bahnschrift 0.236 em),未引入新的抖动来源;逐字观感偏差由走查判定 | 维护者(走查) | | Noto Sans SC **Medium** 字重 | **字重档数限制**(规格 11 Q14 允许「限定字重档数」):只嵌入 Regular + Bold,设计稿 Medium(85 处)不单独嵌入 | 落到 Regular/Bold 或浏览器合成字重;**需走查确认可接受** | 维护者(走查) | | 思源黑体 / 思源宋体 / Crimson Text | **白名单内、本批未嵌入**:许可证据已归档(`public/cockpit/assets/fonts/licenses/`),但设计稿无消费点,嵌入即为死资源 | 不参与渲染;白名单内随时可启用 | 维护者(如需启用) | | `Alimama FangYuanTi VF`(设计稿 18 处) | **无授权证据,未接入**:虽称免费商用但未归档授权证据,按无证据处理(严格白名单制) | 走系统回退链;**不阻断发布**(非核心资源组,且不误导业务语义) | 维护者/设计方(要纳入须先归档授权证据) | | `PingFang TC / MO / HK / SC`(设计稿 99 处) | **Apple 系统字体,不可 Web 嵌入**(规格 11 已锁) | 只作回退栈;`--font` 回退链已含 `PingFang SC`,非 Apple 环境落到 Microsoft YaHei | —(已锁,无需处置) | (2026-10 批次 4 执行时登记,见[执行-批次4:字体接入](17-exec-batch4-fonts.md)与[批次 4 验收说明](../walkthrough-17-batch4.md)。) **2026-10-13 更新五(批次 4 收口,票 17 第五至十一轮)**: | 语义 key / 字族 | 缺口类型 | 回退结果 | 责任人 | | --- | --- | --- | --- | | `font.title`(标小智无界黑 LogoSC Unbounded Sans) | **已撤销**:第五轮曾嵌入(OFL 子集 195 KB)用于顶栏菜单,第七轮维护者否决观感且 D2 取证证实设计稿菜单为 PingFang 常规体(走系统回退栈);槽位与嵌入撤销,**许可证据保留归档**(`embedded:false`),恢复只需重跑 `build-fonts.py` | 无死资源;顶栏菜单走系统黑体(`--font-topbar`),主标题为切图不需字体 | —(已关闭) | | `--font-topbar`(系统黑体) | **新增语义 token(第四轮)**:筛选条/状态 chip 等小字回系统黑体(子集 Noto 在小字号+辉光下发虚,维护者确认);非缺口,是规格 03「按需新增语义 token」的正规落点 | 系统黑体栈,与 `--font` 回退链同源 | —(已关闭) | | 顶栏菜单字体 | **设计稿差异(第七轮取证)**:设计稿 PingFang TC-Regular/Semibold 为 Apple 系统字体 | 按规格 11 走系统回退栈不打包(Windows 落 Microsoft YaHei UI);选中态语义靠白色+Semibold+切图底板表达 | —(已关闭) | **2026-10-12 更新四(批次 2 执行时登记,见[执行-批次2](15-exec-batch2-panel-tokens.md))**: | 语义 key | 缺口类型 | 回退结果 | 责任人 | | --- | --- | --- | --- | | `token.fs.*`(可读性偏差) | 设计稿字号 10–12px 运行时不可读 | 运行时值 11.5–14u(批次 1 维护者走查上调 +1px,经维护者确认沿用为基准);影响全部文字消费组件 | 维护者(已确认) | | `token.panel-gradient` | 设计稿九停、运行时三停;维护者另要求降低地图透底干扰 | 最终 top `rgba(2,9,27,.88)` / mid `rgba(0,28,70,.82)` / bot `rgba(0,15,52,.90)`,CockpitPanel `blur(12px) saturate(115%)`;原设计对应不透明度 .28/.20/.38;影响面板和详情底色 | 维护者(已要求并反馈基本无问题) | | `token.fs-standalone` | 品牌主标题 21u、入口页大标题 26u 为独立档位,无语义槽位 | 保留裸 `calc(N * var(--u))`(>15u,不在归并范围);影响 CockpitShell 品牌位 / CockpitIntro 标题 | 维护者(签收时复核) | | `token.column-detail-width` | 维护者要求两侧栏减宽并扩大设备详情 | 栏宽347u→330u;锚定详情默认340→480px、上限560px并按画布宽收敛;固定详情同步加宽 | 维护者(已确认) | | `token.point-status-colors` | 蓝湖/原实现四种中性状态共用灰色难辨 | 离线银灰、无设备浅灰、未知紫、未关联橙;`point-*` tokens同步统计、标签、地图;业务状态与优先级不变 | 维护者(已确认) | | `token.chart-categories` | 原单色图表难分工单及其他类别 | 行业四语义色、八分类色;已取消红/延期黄/结案绿;各图表共用tone映射,不声称全为设计稿实测色 | 维护者(已确认) | | `ui.section-status-dot` | 数据状态胶囊占宽;维护者要求圆点与标题右对齐 | 状态文字保留无障碍与hover/focus提示,圆点在标题行右侧;统计字段完整换行、里程独行、图例信息包在框内 | 维护者(已确认) | **2026-10 更新六(批次 5 装饰执行时登记,见[执行-批次5](18-exec-batch5-decorations.md)与[批次 5 验收说明](../walkthrough-18-batch5.md))**: | 语义 key | 缺口类型 | 回退结果 | 责任人 | | --- | --- | --- | --- | | `decor.grid-scanline-vignette` | **设计稿未覆盖(现状维持,P3)**:全局细网格、地图扫描线、地图/引导暗角、面板辉光与 L 形切角、氛围径向辉光在蓝湖 9 画板中无对应图层,属现有实现自己的氛围增强 | 按规格 12「设计稿未覆盖项维持现状」保留;全部代码化(CSS 渐变/mask),无位图资源;未声称有设计稿依据 | 维护者(走查复核) | | `decor.brand-pool` | **光池为推断消费点(P3)**:D6 品牌标题后方 489×128「光」位图按设计 realFrame 等比铺放,但标题在运行时定稿为 404u(非设计 470 逻辑尺寸),偏移 -19,-1 按比例换算,非像素级对位 | 已入 manifest `icon.brand.pool`(formal)+ 语义注入;观感偏差走查判定,偏差只调 CSS 不动素材 | 维护者(走查) | | `decor.unconsumed-candidates` | **11 个装饰候选无消费点**(`brand-glow-1/3`、`panel-corner-*`×4、`panel-subtitle-*`×2、`select-bg*`×2、`topbar-line`):设计方切图批次里含这些图,但驾驶舱无对应落点 | 按共识 §1「没有消费点的图不进运行时」挪入设计归档 `unconsumed-decor/`(LEDGER.md sha256 台账);将来设计确认落点后从归档恢复、登记、接线 | 维护者/设计方 | | `decor.panel-corner-color` | **四角切角色值收口**(非缺口,留痕):4 处 data-URI 内联主蓝色值改为白几何母版 + mask 染 `--panel-line-hi`;观感应与改前完全一致 | 色值单一来源达成;走查若发现染色异常按走查单 §4 判缺陷 | 维护者(走查) |