# Changelog 所有显著改动按 [SemVer](https://semver.org/) 记录于此。格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)。 ## [Unreleased] ### 品牌标识 · 几何 K 图标(favicon / 顶栏标记 / theme-color) > 起因:品牌此前**没有任何图形标识** —— 唯一 favicon 是内联 data-URI 里的字母「A」, > 那是 v2.0.0「Aurora Admin → Kole UI」改名时漏掉的一处(PC 顶栏也是「A」, > 而移动端站已是「K」;移动端文档站则完全没有 favicon)。 > 落地:几何 K(三笔画断笔描边),两端同源,含 favicon / 顶栏标记 / theme-color。 #### 设计 - **几何**:24 网格上三个**互不接触**的笔画(竖笔 + 上斜 + 下斜),圆头描边。 笔画不接触既表达「独立组件拼组成系统」,也保证 16px 浏览器标签页尺寸下不糊。 - **描边 2.25**:在 24 网格下,16px 渲染时正好是 **1.5px** —— 等于规范原文 「线性图标,描边1.5px」(`.design_library/kole-ui/specs/组件1.txt`)。 实测比对了 1.5 / 1.875 / 2.25 三档在 20px 顶栏与 16px 标签页下的观感。 - **圆角 rx=6**(24 网格)= 32px 下 8px,即令牌 `--kole-radius-large`。 #### 取色分两套(刻意,不是不一致) - **favicon 硬编码** `#2F54EB` + `#FFFFFF`:它渲染在**浏览器标签栏**,不继承 `html.kole-dark`。 若走令牌,暗色下 `--kole-color-text-inverse` = `#14161C`,会变成「亮蓝底 + 近黑标记」, 在浅色标签栏上反而发闷。 - **两端顶栏标记走 `currentColor`**:实测暗色下自动解析为 `rgb(20,22,28)`、 底色转 `rgb(107,140,255)`(令牌化行为保真,与同页其它图标一致)。 #### 新增 - `theme-color` 双条(light `#FFFFFF` / dark `#1C1F26`,取 `--kole-color-card-bg`, 即 `.topbar` / `.m-top` 的 background,色值与视觉连续)。PC 写在 `site/index.html`; 移动端由新增的 `__BRAND_HEAD__` 占位符经 `tools/build-mobile.mjs` 注入 7 个模板。 #### 修正 - `site/index.html` 的 favicon 字母 `A` → 几何 K;顶栏 `.logo-mark` 的 `A` → 几何 K (**类名与 32×32 盒模型不变** —— ≤1366px 时它是顶栏唯一品牌标识)。 - `tools/build-mobile.mjs` 移动端顶栏标记 `K` 文字 → 几何 K 图形(保留 `class="m-logo-mark"`, `verify-mobile-docs` 会逐页断言它存在)。 - `site/app.js` 首页 hero 标语 `KOLE ADMIN DESIGN SYSTEM` → `KOLE UI DESIGN SYSTEM` (同一改名的变形残留)。 - 移动端文档站 7 个模板补 favicon(此前 `rel="icon"` 计数为 0,标签页显示默认地球图标)。 #### 验收 - 门禁:`verify-site-routing` OK(103 / 412 / 521)· `verify-site-routes` OK(零 4xx)· `verify-mobile-docs` OK(12 条 · 53 页)· `verify-mobile-site` OK(263 条 · 50 页, 控制台 0 错误)· `verify:isolation` OK(31 条)· `verify:theme` / `verify:nav` / `verify:i18n` / `verify-icons` 全 OK。 - 回归:PC **1464/1464** · 移动端 **807/807**,**各连跑 8 次一致**。 - 浏览器实测:PC 与移动端 favicon **405 字节逐字节一致**;页面 DOM 中 `>A<` 清零; PC 站控制台错误从 1(favicon 404)降为 **0**。 - 已知边界:`og:image` / `apple-touch-icon` / web manifest 未做(需位图管线, 见 ROADMAP S8-P4)。 ### 图标系统(PC 5 端 + 移动端 6 端 + 全量图标库 + 预览页) > 起因:用户要求「图标组件参考 TDesign / Element 等主流组件库,看他们的 icon 是怎么专门设计的、 > 设计内容有哪些,覆盖他们全部拥有的 icon 图标和功能」。 > 落地:**2576 个图标**(TDesign 线性 1334 + 面性 1020 + Element Plus 293,均 MIT), > 11 个端实现全部接通,新增 5 个构建/门禁工具与 1 个图标预览页。 > 冻结规格:`.design_library/kole-ui/icons/ICON-SPEC.md`。 #### 新增:图标数据管线(离线可复现,上游校验和钉死) - `tools/fetch-icon-sources.mjs` — 拉取并**归一化**上游 SVG → `sources.json`。 逐包校验 sha256(防「某天图标悄悄变了」);纯函数可单独 import(无副作用)。 - `tools/build-icons.mjs` — 编译出 `manifest.json`(清单)/ `registry.json`(渲染数据)/ `viewbox.js`(viewBox 例外表)/ `core.js`(内联运行时)/ `ATTRIBUTION.md`(MIT 归属,分发必带)。 - `tools/build-icon-aliases.mjs` — 别名层,让 **Element UI 全部 282 个历史图标名**与 移动端既有 9 个字形名都能落到真实图标(**旧调用点零破坏**)。 - `tools/inject-icon-table.mjs` — 把 core 表注入 11 个端实现的标记块,杜绝「11 份手抄表必然漂移」。 - `tools/verify-icons.mjs` — **11 条静态断言**(产物一致 / 无 `view-box` 残留 / 描边全 1.5 / core 可渲染 / 别名不遮蔽 / 各端都能查到名 / 分组覆盖率 / 路径数字与源逐值一致)。 #### 修正:两个上游缺陷在构建期抹平(此处是本仓库的增量,不是照抄) 1. **`view-box` 拼写错误**:TDesign **全部 2356 个** SVG 把属性写成 `view-box`(无效属性, 浏览器忽略 → 图标按默认视口缩放)。构建期两种拼写都读,产物统一写回规范的 `viewBox`。 2. **描边宽度 2 → 1.5**:上游为 `stroke-width="2"`(24 网格),本仓库规范 (`组件1.txt`「图标规范:线性图标,描边1.5px,尺寸16/20/24px」)要求 1.5,构建期归一。 另丢弃 `fill="transparent"` 命中区路径(那是热区不是视觉内容)。 #### 修正:自测发现的数据损坏缺陷(构建期把坐标改错) - **现象**:归一化把路径数字四舍五入到 2 位小数,看似无害;但 SVG path 允许「隐式分隔」—— `q-13.005.48-22.5` 是**三个**数(`-13.005`、`.48`、`-22.5`,靠 `-` 和 `.` 当分隔符)。 把 `-13.005` 舍成 `-13` 后,后面的 `.48` **粘成** `-13.48` —— 那是另一个坐标, 图形画错**且不报任何错**。实测踩到 Element Plus 的 `quartz-watch`(靠浏览器控制台才发现)。 - **修法**:原本有小数位的数字,输出**至少保留 1 位小数**(`-13.005` → `-13.0`), 隐式相连的 `.48` 不可能再被吸收;并在 `optimizePath` 内**复核数字序列**,不一致就原样返回。 - **防复发**:新增门禁断言 **V8「路径数字与源逐值一致」**,比对全部 2576 个图标。 已做**变异测试**:把该 bug 重新注入 → V8 当场 FAIL(`数字个数 461 ≠ 源 462`),判据有区分力。 - 代价:`registry.json` 707KB(修前 677KB,+30KB 换正确性)。 #### 修正:非 `` 图形被静默丢弃(覆盖率审计发现) - **现象**:解析器只认 ``,而上游有 **36 个文件**用 `` / `` 表达图形(TDesign 的 `circle` / `round` / `brightness` / `image` 等)。这些图形被**静默丢掉** —— 图标页面上"渲染成功"却是空的,构建与回归都不报错。TDesign 的 `circle` 与 `round` 两个图标 因此整个消失,是**覆盖率审计**(对三个参考库逐名比对)才暴露的。 - **修法**:解析器同时处理 `` / `` / ``,把圆与椭圆等价换算成 path 的两段 arc(`M cx cy-r A r r 0 1 1 cx cy+r A r r 0 1 1 cx cy-r Z`)。 - **结果**:图标数 2574 → **2576**;对三家参考库的覆盖率现为 **TDesign 2356/2356、Element Plus 293/293(各 100%)**、Element UI 280/282(余 2 个是解析碎片名)。 - 校验:两个恢复的图标在浏览器实测有真实几何(path 长度 63 / 44,分别对应 r=10 与 r=7 的圆)。 #### 分层与体积(按实测决定,不是拍脑袋) - **core 151 个内联**(`core.js` 35KB),`standard` 1989 / `extended` 434 按需加载。 - **为何不全内联**:全量 670KB,内联等于给每一页都加 670KB,直接违背 ROADMAP 的性能预算精神。 #### 组件 API(PC 5 端 + 移动端 6 端,语义统一) - props:`name` / `size`(关键字 `small|default|large|xlarge` **或任意 CSS 长度**,对齐 TDesign 双模式)/ `tone`(`default|brand|secondary|danger|success|warning`)/ `spin` / `label`。 - **向后兼容**:PC 既有 `icon` prop(字形字符,默认 `'★'`)与移动端既有 9 名字形表全部保留,`name` 优先。 - 无障碍:`label` 有值 → `role="img"` + `aria-label`,无值 → `aria-hidden`; `spin` 在 `prefers-reduced-motion: reduce` 下停转;语义色对比度 ≥ 3:1(实测 5.10–5.87:1)。 - **viewBox 按「路径串 → 网格」反查而非按名**:别名指向的 1024 网格图标若按名查会取错网格 (实测影响 160 个名字,会导致图标拉伸变形)。 #### 新增:图标预览页 `site/icon-preview.html` 规范 `组件5.txt`「图标预览 IconPreview:展示系统所有图标 / 网格布局,支持搜索 / 点击图标复制名称或代码 / 可调整图标大小」声明已久但从未实现。本次补齐: 2576 图标网格、搜索、点击复制名称、Shift+点击复制内联 SVG、四档尺寸切换、仅线性过滤; 分两段加载(索引 51KB 先出骨架,路径数据按需); 入口挂在图标组件页代码条 footer,i18n 双语(`图标预览` / `Icon gallery`)。 #### 已知未覆盖 / 遗留 - 移动端 uni-app 端用 **CSS mask(data-URI SVG)** 承载字形(小程序无 DOM、无内联 SVG)。 H5 目标已实测;**mp-weixin / app-plus 的遮罩渲染未在真机验证**,已登记进契约 `unknowns`。 - `verify-emits-parse.mjs` 的文件数期望值陈旧(158,应为 103×2=206)—— **本次之前就存在** (`git show HEAD:` 确认),已登记为 ROADMAP `S8-P1`。 - `verify-cross-platform.mjs` 把注入的图标数据表误判为组件类名(540 条里 533 条是噪声)—— 已登记为 ROADMAP `S8-P2`(判据不放宽,让门禁学会跳过数据块)。 - `组件5.txt` 声明的 47 个工具/模板组件里 **46 个仍未实现**(本次只补了 IconPreview)—— 已登记为 ROADMAP `S8-P3`,含「走 `frameworks/` 正式组件还是 `site/` 工具页」的决策点。 ### Mobile · 顶栏对齐 PC + 平台入口去重(移动端站导航栏改造) > 起因:用户要求「移动端组件的导航栏参考 PC 端组件导航栏优化(上面跳转 PC 和移动的下拉框也重复了)」。 > 实测确认两条问题,逐项修掉。 - **去重:平台切换从顶栏移除**。移动端站顶栏原有一个 `[PC 端] [移动端]` 分段胶囊,与同一页左栏的 「平台」组指向同一跳转(实测 DOM:`a.mp-item` 与 `a.m-side-link.m-side-platform` 的 href 均为 `../index.html`)—— 同一件事两处入口。PC 站顶栏从来没有这个控件(只有左栏一处), 故删顶栏那份,两端现在都是**左栏唯一入口**。改动同时断言「删的是重复的那个,不是删光」: `verify-mobile-docs` 的 E7 从「断言顶栏有平台切换」改为「断言左栏有平台入口」。 - **顶栏逐项对齐 PC**(此前只有结构同名,控件实现不同源): - 高度 56px → **60px**;内容加 **1180px 居中容器**(`.m-top-inner`,与 `.m-body` 同宽, logo 与左栏左边缘对齐;此前内容铺满视口、与下方内容左边缘错位)。 - 激活项补 **2px 底部品牌指示条**(`.m-nav a.active::after`,PC `.topnav a.active::after` 同款); 此前只有文字变色。 - 版本角标 → **可点版本下拉**:`` 换成 `#m-ver-trigger` + `#m-ver-menu`, 清单从部署根 `versions.json` / `site/versions.json` 两份按序取(不并行 —— 快照页那份必然 404, 并行会把 404 记进控制台,而站点门禁的零控制台错误是硬断言);拿不到清单时 `data-single="1"` 退回不可点角标(与 PC 同一语义)。路径校验只放行 `".."` 与 `x.y.z`,防清单把人带去外站。 - 主题触发器补 **三态图标**(月亮 / 太阳 / 显示器,PC `.theme-icon` 同款):显式选择时按时态给图标, 自动模式恒为显示器图标;此前只有文字标签。 - **零运行时依赖不变**:新增的版本/主题逻辑是构建期内联脚本(`COPY_SCRIPT`),不引包。 - **顺手修掉一处过期硬编码**:移动端站文案里的 PC 组件数写死为「79」, 而 S6-P21 组件族参数化后 PC 索引已是 **103**(实测 `components/index.json`)。改为构建期从 PC 索引实测读取 (模板占位符由 `build-mobile.mjs` 灌入),拿不到索引时退回中性表述而非编造数字。 涉及:总览页、FAQ、平台与端页的正文与覆盖矩阵、以及 `dist/mobile/README.md` 与 manifest 的 `isolatedFrom`。 **验收(原样)**: ``` node tools/verify-mobile-docs.mjs → [OK] 12 条断言 · 53 页(E7 判据已同步去重) REG_BASE=http://127.0.0.1:3457 node tools/verify-mobile-site.mjs → [OK] 263 条断言 · 50 页 · 控制台错误 0 · 演示帧 281/281 REG_BASE=http://127.0.0.1:3457 node tools/run-mobile-regression.mjs → passRate 100% | pages 47 (all-pass 47) | assertions 804/804 | N/A 10 REG_BASE=http://127.0.0.1:3457 node tools/run-regression.mjs → passRate 100% | pages 103 (all-pass 103) | assertions 1405/1405 | N/A 50 PC 与移动端回归各连跑 8 次,结果逐次一致(40/40 全绿) ``` 浏览器实测(Playwright,1440px):顶栏 60px / 内容容器实测 1180px / 激活项 `::after` 实测 `2px rgb(47, 84, 235)` / 顶栏内 `.m-platform` 计数 0 / 版本下拉实测 1 个选项且 `data-single="0"` / 切夜间后图标 `m-icon-sun:block` 且 `html.kole-dark` 生效;320–768px 四档无横向溢出、零控制台错误。 四道移动端门禁全绿:隔离 31 条 / uni-app 9 条 × 50 SFC / 文档 12 条 · 53 页 / 站点 263 条 · 50 页。 ### Mobile · 批次 E/F:移动端组件 36 → 47(两批子 agent 并行 + 新增「磁盘↔索引」双向门禁) > 继续 `/son` 派活推进 TDesign 清单覆盖。批次 E(typography / segmented / sticky / overlay / popover / message) > 与批次 F(picker / cascader / colorpicker / upload / table)并行产出 11 个组件 × 8 文件 = 88 文件, > 规格 §37–§47。索引 36 → **47**,实现 216 → **282**,移动端回归 597 → **804 条断言**。 - **给每个组件预分配规格编号**(§37–§47):上一轮两个子 agent 并存时存在编号撞号风险(撞号会被合并脚本按幂等规则整节跳过), 本轮在派单里逐组件指定编号,合并时零冲突、规格 §1–47 连续。 - **新增反向门禁 B1b(两个子 agent 独立报的同一条缺口)**:`verify-mobile-isolation.mjs` 原先只查 「索引里的组件有没有实现文件」,**不查「磁盘上的实现文件有没有进索引」**——于是子 agent 产出的组件在合并前 完全不被任何门禁覆盖(不在索引里 = 不被检查),属静默缺口。现补反向断言:磁盘前缀集合必须等于索引前缀集合, 不一致直接报「未登记:X, Y(跑 node tools/merge-mobile-batch.mjs 合并)」。断言数 30 → **31**。 - **修掉两处探针误判(都是工具侧,不是内容缺陷)**: - `verify-mobile-site.mjs` 的总览页在 47 个卡片时只渲染 43 个 —— 预览帧 `loading="lazy"`, **一次 `scrollTo` 到底会跳过中间帧**。改为逐段滚动(每 800px 一次)后再判定,实测 281/281。 - 同一脚本把收集器的 `net::ERR_ABORTED` 记为控制台错误 —— 那是 `_collect.html` 在帧装载完成后 **主动** `removeAttribute('src')` 释放帧造成的在途请求中断,是设计行为。判据改为忽略 `ERR_ABORTED`, 其余(404 / ERR_INVALID_URL 等)仍然计错。 - **子 agent 自修的真实缺陷(都带证据)**:`Sticky` 的 `is-stuck` 判定在默认偏移下滚动 0 就已贴合(改为与容器 padding box + 偏移量比较,含 1px 边框补偿); `Message.jsx` 把 `onClose` 写进 `useEffect` 依赖 → 宿主传内联箭头函数时计时器永远不到点(回调移到 `useRef`); `Sticky`/`Message` 演示页缺实际执行的监听器致 `data-behavior` 静默失效; `Table` 可点行不可聚焦(真实引擎报 `matrix:keyboard-reachable`)→ 补 `tabindex`/`role`/`aria-selected`/Enter 键路径; `ColorPicker` 的色板 hex 写在行内 style 被 `no-hardcode-hex` 判据扫到 → 改走行内自定义属性(CSS 零 hex,色值只存数据层)。 - **规划偏差(子 agent 主动对齐既有约定)**:`disabled` 从变体维度降为状态类 —— 全仓 47 份契约无一把它当变体, 同意;`picker`/`cascader`/`segmented` 的初判分类经我核对后修正为 input/navigation(PC 同源六分类口径)。 **验收(原样)**: ``` node tools/verify-mobile-isolation.mjs → [OK] 31 条断言(含新增 B1b 反向断言) node tools/verify-uniapp.mjs → [OK] 9 条断言 · 50 个 SFC node tools/verify-mobile-docs.mjs → [OK] 12 条断言 · 53 页 REG_BASE=… verify-mobile-site.mjs → [OK] 263 条断言 · 50 页(0 控制台错误、演示帧 281/281) node tools/run-mobile-regression.mjs → 100% | 804/804 | 47/47 页 | N/A 10 | 0 超时 node tools/run-regression.mjs → 100% | 1405/1405 | 103/103 页(PC 侧未被污染) node tools/pack-deploy.mjs --tar → OK(282 实现 / 47 文档页 / 47 测试页) ``` **部署**:暂存树哈希与本地一致(`936742e98d061a30`)→ 替换重建 → 五项验收全过、11 个新增组件页全 200、容器 0 error; 公网 `data.mobile.json` 报 **47 个组件**。 **剩余 23 个**(已写进 ROADMAP S7-P23):config-provider / Fab / BackTop / Drawer / Indexes / SideBar / Tabs / Calendar / DateTimePicker / TreeSelect / CountDown / Empty / Footer / Image / ImageViewer / QRCode / Result / Skeleton / Swiper / Watermark / DropdownMenu / Guide / PullDownRefresh。 ### Docs · 模板页库 1 → 5(S4-P11:把组件组合成可复制的后台页面) > 起因:用户要求「为组件库设置一个合适的 UI」。定位到 ROADMAP 中唯一「🟢 可开工」的任务 —— S4-P11 模板页库。 > 其依据写得很直白:「模板页是『能否直接用』的关键 —— 用户要的不是组件,是页面」。此前只有 1 个场景页。 - **新增 4 个模板页**(`site/scenario/`,纯 HTML + 原生 JS、零依赖): - `login.html` — 输入类组件 + 表单校验。字段级错误提示(指出字段、说明原因、给修正方向)、 密码显隐切换、提交加载态 → 成功态、账号锁定等业务错误分支。 - `dashboard.html` — 侧边导航 + 4 张指标卡 + SVG 趋势图 + 渠道占比进度条 + 待办表格 + 分页。 时间范围切换会重算指标与图表;含折叠面板。 - `order-list.html` — 筛选表单 + 表格 + 批量操作条 + 分页 + 详情抽屉。 37 条示范订单;筛选/全选/批量审核/抽屉(Esc 关闭、焦点归还)全部可用。 - `settings.html` — 侧边分区 + 表单 + 开关组 + 单选/复选组 + 危险操作二次确认。 - **接入首页**:`site/app.js` 首页新增「模板页库」区块(5 张卡片,新窗口打开);`site/style.css` 补 `.home-note`。 - **sitemap**:`build-site.ps1` 把 5 个模板页写入 sitemap(521 URL)。新增行全为 ASCII,守住 PS5.1 的 ASCII-only 约束。 - **i18n**:`site/i18n.js` 补 13 条英文(模板页库标题与 5 张卡片),中文源串作键的既有约定不变;`verify:i18n` 316 键全覆盖。 - **新增门禁 `npm run verify:templates`**(`tools/verify-templates.mjs`,54 条浏览器断言,已接入 CI): 令牌生效 / 非白屏 / 零控制台错误 / 零 4xx / 逐页交互 / 375–1024px 无横向溢出。 - **判据修正(`tools/verify-site-routing.mjs`)**:sitemap URL 总数原为硬编码 `1 + 组件数×5`, 现改为「**按 `site/scenario/` 磁盘上实际存在的 .html 逐个核对 + 计入总数**」。 理由:硬编码在新增模板页时只会静默漏检(sitemap 少了页面而断言仍绿); 改后「新增/删除模板页却忘记同步 `build-site.ps1`」会直接红。**这是加强而非放宽** —— 新增了 5 条逐文件断言。 **模板页实测(原样)**: ``` node tools/verify-templates.mjs → [templates] OK — 54 checks passed node tools/verify-site-routing.mjs → [routing] OK: 103 components / 412 platform shells / 521 sitemap URLs node tools/verify-i18n.mjs → [i18n] OK — 16 checks passed(316 keys covered) node tools/run-regression.mjs → 100% | 1405/1405 | 103/103 页 | N/A 50(八次连跑一致) ``` **过程中被测试逮到并修掉的 4 处真实缺陷**(都不是判据问题): 1. **进度条高度渲染为 0** —— `components.css` 只聚合 6 个**核心**组件,`ProgressVariants` / `DashboardCard` 这类扩展组件的样式根本没被加载(类名在、样式缺,页面不报错、只是画不出来)。 修法:4 个模板页按需 `` 各自的 `frameworks/*.css`(这些文件均为纯令牌自包含), 而不是在模板页里重画一遍组件。 2. **指标卡标题与图标未两端对齐**(`display:block` 而非 `flex`)—— 与上条同根因。 3. **设置页脏检查存在永久闩锁** —— 原写法 `if (saved) return` 导致「保存过一次」之后表单再也不会被标记为脏; 且「放弃修改」只硬编码还原 5 个字段,IP 白名单与通知勾选漏在还原之外。 修法:改为**快照式**脏检查(基线 = 上次保存值,逐字段比对),于是「改回原值自动回到干净态」, 日后新增字段也不必再补还原代码。 4. **保存竞态** —— 保存有 700ms 模拟延迟,期间「放弃修改」仍可点,会拿到上一份基线,表现为数据被还原成旧值。 修法:保存进行中两个按钮都禁用。 ### Mobile · 批次推进:移动端组件 5 → 36(三批子 agent + 合并脚本 + 修行为断言静默缺口) > 起因:用户要求「参考 TDesign 移动端组件清单,按批次补全缺的组件」,随后 `/son`(派子 agent)、`/agi`(全自主)。 > 参考清单 67 个组件,本仓库已覆盖 36 个(含此前的 18 个);流程按 `PLATFORMS.md` §四「六步」固化。 - **三批子 agent 产出 18 个组件**(每个 = 6 端实现 + 规格片段 + 契约 = 8 文件,共 144 文件): - 批次 A:`mobile-icon` / `mobile-layout` / `mobile-link` / `mobile-loading` - 批次 B:`mobile-avatar` / `mobile-list` / `mobile-collapse` / `mobile-progress` - 批次 C:`mobile-input` / `mobile-search` / `mobile-switch` / `mobile-stepper` / `mobile-textarea` - 批次 D:`mobile-form` / `mobile-radio` / `mobile-checkbox` / `mobile-slider` / `mobile-rate` 规格从 §19 连续到 §36(共 36 节);索引 18 → **36 个组件**,实现文件 108 → **216**。 - **新增可复用的合并脚本 `tools/merge-mobile-batch.mjs`**:子 agent 一律不写 `index.json`(避免并发写同一文件), 由主 agent 用该脚本统一合并 —— 它做三件事且幂等:① 按编号把 `spec/parts/*.md` 拼进规格原文(同编号则只归档不拼接); ② 把 `frameworks-mobile/` 里未登记的组件(校验 6 端文件齐全 + 契约存在)写进索引;③ 已拼接的片段归档到 `parts/_merged/`。 - **修掉一个静默缺口(子 agent 复核时发现,价值最高的一条)**:`tests/mobile/_behaviors.js` 的 `PILOTS` 是**硬编码白名单** (只有最初 5 个组件),于是批次新增组件即使在演示页写了 `data-behavior`,引擎也直接 `return []` —— **行为断言静默不跑,断言总数悄悄少一截**。修法:作用范围改为「演示页里**真的**写了 `[data-behavior]` 的组件」 ∪ 兜底名单,由 `build-mobile.mjs` 在生成测试页时把派生结果注入 `window.__koleBehaviorSlugs`。 实测:行为断言覆盖 5 → **31 个组件**,断言条数 8 → **34 条**(全部 pass)。 - **修掉一处判据过窄(上一轮遗留)**:`pack-deploy.mjs` 的「frameworks-mobile 实现文件数」按索引动态算, 但打包时批次文件已在磁盘而尚未合并进索引 → 断言误报。现在按「索引组件数 × 端数」与磁盘实际双向核对, 不一致时直接指出差额(本次实测:156 vs 186,正是未合并的批次 C)。 - **修掉一处探针误判**:`verify-mobile-site.mjs` 统计总览页演示帧时只看到 20/26 —— 预览帧是 `loading="lazy"`,**视口外的帧不会加载**(浏览器行为,不是缺陷)。判据改为先滚到底再判定, 实测 26/26、现在 36/36 全部正常渲染。 - **子 agent 自修的真实缺陷**(都在报告里给了证据):`