@qilitt-mickey/vue3-temp-skill 1.1.62 → 1.1.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,7 +30,7 @@ parser match(确定性翻译)→ 施工坐标 → AI 按坐标改代码 →
30
30
 
31
31
  无论哪条来路,落地流程一律走下文「执行流程」。
32
32
 
33
- **上下文纪律(防上下文溢出,与流程红线同级)**:
33
+ **阅读纪律(防上下文溢出,与流程红线同级)**:
34
34
 
35
35
  1. **词典走 parser,禁直读全文**:`mapping/` 下 JSON 是 parser 的事实源,不是给人(AI)通读的——查点位用 `parser query <id>`、查清单用 `parser list`,**禁止整文件读入 `mapping/scenes/*.json` / `mapping/basic/*.json`**(仅 validator/regression 维护场景或 parser 明确报错需要人工核对单条时,用 `Grep` 精确抽取相关条目,不整读)。
36
36
  2. **落地会话禁读设计侧规范库**:设计技能的 `page-specs/`(规范/令牌/效果图)不属于项目侧视野——项目侧消费的是**变更集 + oracle.json + 登记表**三个交付物;`oracle.mockup` 指向的效果图由 `resolveFirstExisting` 跨库解析给 parser 使用,但人(AI)**不打开、不阅读设计侧效果图与规范文件**。
@@ -113,7 +113,7 @@ parser match(确定性翻译)→ 施工坐标 → AI 按坐标改代码 →
113
113
  - `pending` 数组声明的是设计侧新点位,直接归入 L3 处理(不是错误)。**注意:pending 不是施工指令**——L3 施工的内容以 `changes[]` 中同 ID 新条目声明的意图为准;设计侧只登记 pending、未在 changes[] 声明意图的点位,落地时按出厂现状处理并在缺口清单中反馈「该点位设计意图缺失」。
114
114
  - parser 校验已实现:schema 硬校验、mapping_version 缺失/不匹配拒绝、禁词与 hex 位置校验、语义 ID 命名校验、`layer` / `apply_via` / `structure_ops` 结构校验。
115
115
 
116
- 各步骤**子文件按需加载**(上下文预算纪律:做到哪一步读哪一份,禁止一次全部通读):
116
+ 各步骤**子文件按需加载**(做到哪一步读哪一份,禁止一次全部通读):
117
117
 
118
118
  | 步骤 | 子文件 | 内容 | 加载时机 |
119
119
  |---|---|---|---|
@@ -52,7 +52,7 @@
52
52
  运行时配置读 localStorage,而 localStorage 只在 `platform-config.Version` 变化时经 `responsive.ts invalidateStorageIfConfigVersionChanged` 重灌。凡施工涉及 `ShowModel` / `Theme` / `EpThemeColor` 等 T 通道字段,**三件套缺一不可**:
53
53
 
54
54
  1. 改 `platform-config.json` 实值(如 `ShowModel: "card"`);
55
- 2. **`Version` 自增一位**(如 0.0.6 → 0.0.7)——漏此步 = 代码对但运行时仍旧形态(历史事故:只改 ShowModel 未动 Version,页签零变化);
55
+ 2. **`Version` 自增一位**(如 0.0.6 → 0.0.7)——漏此步 = 代码对但运行时仍旧形态;
56
56
  3. **渲染取证**:断言新形态类实际挂载(如 `.scroll-item.card-item` 出现在 DOM)——不许只看代码改没改。
57
57
 
58
58
  词典 `admin.layout.tabs.preconditions` 有同款硬闸描述;本三件套对任意 T 通道字段通用。
@@ -53,7 +53,7 @@ node parser/index.js match --batch <changesets-dir>
53
53
  | **G1 suppress 收口** | 条目声明某 `form`,词典 `suppress_rules[form]`(或 forms 描述「suppress 必含 x」内联标记)要求收口的出厂互斥通道未全部出现在该条目 `suppress[]` | 词典条目 `suppress_rules` | `suppress 缺口:…必须收口出厂互斥通道 [x],缺 [x]` |
54
54
  | **G5 几何语境** | 词典 preconditions 含「几何语境随值迁移」标记 ∧ `style` 含 padding/margin 族几何字段落宿主 ∧ 未声明 `suppress_inner` | 词典条目 preconditions 标记句 | `suppress_inner 缺口:…两层之和 ≠ 设计值` |
55
55
 
56
- 三闸与禁词校验同级阻断(`exit 1`)——「新旧形态叠加」「两层 padding 相加」「伪还原只换主题」都是历史事故源(双竖条、28px 列挤压、「还原后布局细节零变化」),不允许靠观感兜底。G8 判据一句话:**「把系统 / 页面改成 X」默认是还原(restore),必须带齐 `scheme` + `oracle.mockup` + `coverage.registry`;只有「显式声明只改主题色、其它不动」才用 `design`**(2026-09-20 事故机制化:还原项目后重跑,无登记表无基线的轻量变更集一路绿灯,落地后「只变了主题、布局细节零变化」;二轮强化再堵住 `oracle`/`coverage` 只给空壳、无 `mockup`/`registry` 芯的写法)。**降级不许静默发生**:变更集 `notes` 与交付说明都须显式写出本次 `mode` 与范围。restore 模式下 G9/G10/G11 同时生效(登记表身份、dims 维度兑现、oracle 基线三道复闸),三者判据细节见上表与「登记表覆盖率」小节。
56
+ 三闸与禁词校验同级阻断(`exit 1`)——「新旧形态叠加」「两层 padding 相加」「伪还原只换主题」都会导致实质错误(双竖条、28px 列挤压、「还原后布局细节零变化」),不允许靠观感兜底。G8 判据一句话:**「把系统 / 页面改成 X」默认是还原(restore),必须带齐 `scheme` + `oracle.mockup` + `coverage.registry`;只有「显式声明只改主题色、其它不动」才用 `design`**(还原项目若用无登记表、无基线的轻量变更集,会一路绿灯、落地后「只变了主题、布局细节零变化」;故须堵住 `oracle`/`coverage` 只给空壳、无 `mockup`/`registry` 芯的写法)。**降级不许静默发生**:变更集 `notes` 与交付说明都须显式写出本次 `mode` 与范围。restore 模式下 G9/G10/G11 同时生效(登记表身份、dims 维度兑现、oracle 基线三道复闸),三者判据细节见上表与「登记表覆盖率」小节。
57
57
 
58
58
  **验收基线输出**:转换计划末尾另打印 `=== 验收基线 oracle ===`(效果图路径 + 待比对点位)与 `=== 覆盖率 coverage ===`(登记项 R / 适用 A / 已兑现 C)。有 `oracle` → 落地后必须跑第 6 步 `verify`;缺 `oracle` / `coverage` → 输出提示,把「补基线 / 补登记覆盖率」回流设计侧(场景还原应给)。
59
59
  **覆盖率校验**:`coverage.covered` 必须等于 `coverage.applicable`、`gaps` 为空,否则打印缺口清单——`C < A` 即**欠声明**(有规范子项未落进 `changes[]`/`visible`/`pending`),属设计侧交付不完整,必须回流,不得在项目侧"猜着补"。
@@ -10,14 +10,14 @@
10
10
  node parser/index.js audit --project <目标项目根目录> [<changeset.json…>]
11
11
  ```
12
12
 
13
- 不开浏览器即可查出的三类历史高发缺口:
13
+ 不开浏览器即可查出的三类高发缺口:
14
14
 
15
- | 检查 | 抓什么 | 对应历史缺口 |
15
+ | 检查 | 抓什么 | 对应风险 |
16
16
  |---|---|---|
17
17
  | **挂载点缺失 / 可疑** | `selector` / `anchors.target` 里的类名在项目里**只在样式文件出现、模板没挂**,或**完全找不到** | 列未绑 `class-name` → 金额列右对齐 / 缩略图尺寸永不生效;操作栏规则有定义无引用 |
18
18
  | **死通道** | `anchors` 里的 CSS 变量在项目中**无 `var()` 消费者**(两类豁免:`--el-*` 组件库变量由 EP 运行时消费;设计层已显式接管定义的变量属故意 suppress) | 变量有定义无引用,翻译再准也不生效 |
19
19
  | **词典无此条目** | 变更集引用了词典未建的 ID | L3 新增点位须当场落地并回写临时映射 |
20
- | **G2 structure_ops 施工证据** | 变更集声明 `structure_ops` 的点位,按词典 anchors/selector 语义类名 + `op.node` 提取探针,在**非设计层结构源码**中查证施工痕迹;零命中 = 纯 CSS 冒充结构施工 | 操作列分割线 `add_node` 声明多轮从未施工 |
20
+ | **G2 structure_ops 施工证据** | 变更集声明 `structure_ops` 的点位,按词典 anchors/selector 语义类名 + `op.node` 提取探针,在**非设计层结构源码**中查证施工痕迹;零命中 = 纯 CSS 冒充结构施工 | 操作列分割线 `add_node` 声明了却从未施工 |
21
21
  | **G4 T 通道对账** | `global.brand_primary`(语义值解析 hex)↔ `platform-config.EpThemeColor`;页签 `form` ↔ `ShowModel`;`visible:false` 点位的 `visible_prop` 开关 ↔ platform-config 实值 | 变更集孔雀绿、platform-config 残留旧主题;flat 页签叠加 chrome 结构 |
22
22
 
23
23
  挂载点疑似但**设计层文件已承载该类名** → 降级不阻断(C 通道由 design-shell 兜底是合法落点)。G2 / G4 违规与挂载点问题同置 `exitCode 1`。审计报错 = **能力缺口**:当场按 `structure_ops` 补挂载 / 补消费者,交付说明单列申报;不得以「词典没建」为由跳过。审计通过 ≠ 还原达标——**静态审计查不出「值对了、位置不对」**,那要靠第 6 步渲染态验收。
@@ -11,11 +11,11 @@
11
11
  - `visible: false` → 按条目 `visible_prop`(如 `platform-config.json` 的 `HideTabs`)或组件 `v-if` 隐藏;无现成通道时 `display: none`,作用域限定在条目 `style_scope` 内。**不删除任何代码行。**
12
12
  - `position` → 优先用 flex 顺序(`order` / DOM 位置调整),禁止绝对定位像素坐标。
13
13
  - `form` → 按条目 `forms` 枚举切换(如 tabs 的 `chrome`/`card` 走 `platform-config.json ShowModel`;内容区滚动模式走 `admin.content.container` 的 form(`fixed`/`scroll`/`auto` → 路由组件根节点 `data-content-mode` 属性,`auto` 为省略即钩子类探测)。枚举外的形态 → 报告,不猜。
14
- - **结构维度缺失即申报,禁止「只改令牌冒充落地」**:变更集把结构/方位/有无类意图写进 `style`(如指示条只在 `style.menu_active_indicator` 出现、无对应 `form`)时,按「结构意图缺失」处理——交付说明申报「设计侧需补 form + 几何 + 色值」,不得只覆盖颜色令牌交差(历史事故:竖条只换令牌 → 图上有、页面上没有)。
14
+ - **结构维度缺失即申报,禁止「只改令牌冒充落地」**:变更集把结构/方位/有无类意图写进 `style`(如指示条只在 `style.menu_active_indicator` 出现、无对应 `form`)时,按「结构意图缺失」处理——交付说明申报「设计侧需补 form + 几何 + 色值」,不得只覆盖颜色令牌交差(否则会出现「图上有、页面上没有」)。
15
15
  - `form` 的落点按上文「落地三落点判据」执行:**有 DOM/配置通道走通道,无通道需新节点走结构增量,纯视觉形态走设计层样式文件**。当某形态在本项目只有样式表达(如菜单指示条方位)时,该 form 允许落到样式层——这与「禁止把内容区高度模式降级成 SCSS」不冲突,判据是**该形态有没有非样式通道**。
16
16
  - `layout_type` → 改 `platform-config.json Layout` 字段,值域 `vertical/horizontal/mix`。**大屏全屏沉浸式等独立页不走此通道**(设计侧不填 `layout_type`,点位走 L3 落地)。
17
17
 
18
- **存在性收口(通用机制,第 2 步随结构处理)**:变更集未声明的**出厂多余元素**(设计效果图上不存在的按钮/图标/入口,如顶栏设置按钮)→ 按各条目口径处理:有条目者在对应点位上以 `visible:false` 收口(代码保留,`v-if`/`display:none`);无条目者列入缺口清单申报「设计侧未声明,按无此元素收口」,同样以隐藏通道落地。禁止既不声明也不收口、让出厂元素顶替设计效果(顶栏设置按钮漏收口已实证:效果图无此按钮,落地后仍显示)。反向同理:**设计声明了而出厂没有的元素**(如欢迎区问候语)必须按条目 `$note`/设计规范补齐结构(结构通道豁免底线二),缺失 = 未交付。
18
+ **存在性收口(通用机制,第 2 步随结构处理)**:变更集未声明的**出厂多余元素**(设计效果图上不存在的按钮/图标/入口,如顶栏设置按钮)→ 按各条目口径处理:有条目者在对应点位上以 `visible:false` 收口(代码保留,`v-if`/`display:none`);无条目者列入缺口清单申报「设计侧未声明,按无此元素收口」,同样以隐藏通道落地。禁止既不声明也不收口、让出厂元素顶替设计效果(如顶栏设置按钮:效果图上没有,漏收口则落地后仍显示)。反向同理:**设计声明了而出厂没有的元素**(如欢迎区问候语)必须按条目 `$note`/设计规范补齐结构(结构通道豁免底线二),缺失 = 未交付。
19
19
 
20
20
  **出厂演示占位内容等价(通用机制,第 2 步随存在性收口一并处理)**:模板演示页常带有**占位说明性文案与演示按钮**(用于演示"此处可放控件"的说明文字、占位操作列)。这类内容**不是设计效果**——凡落在设计效果图对应角色上的演示占位内容,必须按「效果」等价逻辑处理:
21
21
  - 有设计对应操作(设计声明了按钮/操作列的形态与语义)→ **替换为设计对应内容**(如把占位操作列替换为"查看/编辑/更多"及其形态),不得保留演示文案;
@@ -52,9 +52,9 @@
52
52
 
53
53
  - 变更集给了 `layer` → 严格按 `layer` 从条目 `anchors` 取对应选择器(parser 已在转换计划里给出 `@ … · host/inner 层`)。
54
54
  - 变更集**没给** `layer`、但条目 `preconditions` 指出必须落内层(如 EP 表头 `white-space`)→ 按 `preconditions` 落 inner 层,并在交付说明注明「设计侧未给 layer,按条目前置条件处理」。
55
- - **内层盒属性族强制校验**:`white-space` / `text-overflow` / `overflow` / `word-break` / `text-align` / `line-height` / `vertical-align` 这组属性**只在内层文本盒生效**——逐字段核对 `layer`;未指认且条目前置条件也没说 → **退回设计侧补声明**,禁止默认落 host(历史缺口:表头「禁止换行」落 host 被内层默认 `normal` 吃掉 → 表头竖排、行高撑大、列内容被压)。
55
+ - **内层盒属性族强制校验**:`white-space` / `text-overflow` / `overflow` / `word-break` / `text-align` / `line-height` / `vertical-align` 这组属性**只在内层文本盒生效**——逐字段核对 `layer`;未指认且条目前置条件也没说 → **退回设计侧补声明**,禁止默认落 host(否则会被内层默认 `normal` 吃掉 → 表头竖排、行高撑大、列内容被压)。
56
56
  - 常规分工:高度 / 背景 / padding 落 host;文本换行、省略、对齐落 inner。
57
- - **几何语境必须随值迁移(双重内边距,历史缺口:表头标题截断成 类…/包…/操…)**:出厂内层文本盒自带 padding 时(EP `.el-table .cell` 出厂 `padding: 0 12px`),把设计的 16px 落到 host 后**必须同步清零内层自带 padding**——否则实际内边距 = 16+12 = 28px/侧,列宽被挤、表头标题被省略号截断、视觉不适配常规。判据:**效果图的距离语义是「列缘到文字」的总距离;宿主/内层两层结构下必须拆成两段落地,两段之和等于设计值**。凡向 host 落 padding/border 类几何值,先查出厂内层盒的自带同族值再决定是否归零。
57
+ - **几何语境必须随值迁移(双重内边距,否则表头标题会截断成 类…/包…/操…)**:出厂内层文本盒自带 padding 时(EP `.el-table .cell` 出厂 `padding: 0 12px`),把设计的 16px 落到 host 后**必须同步清零内层自带 padding**——否则实际内边距 = 16+12 = 28px/侧,列宽被挤、表头标题被省略号截断、视觉不适配常规。判据:**效果图的距离语义是「列缘到文字」的总距离;宿主/内层两层结构下必须拆成两段落地,两段之和等于设计值**。凡向 host 落 padding/border 类几何值,先查出厂内层盒的自带同族值再决定是否归零。
58
58
 
59
59
  **B2. 出厂形态互斥收口 `suppress`(治「新形态上了、旧形态残留」)**——条目带 `suppress` 时,逐通道执行收口,**收口优先走令牌重映射**(在令牌宿主作用域重声明令牌,零权重战争),令牌不存在才写属性:
60
60
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  ### 第 3 步附加(之二)· 覆写优先级消费( 硬步骤)
8
8
 
9
- 第 1 步输出的 `▸ 覆写优先级 priority` **不是提示,是落地写法的硬要求**。每落一条规则前先按策略决定写法;写法错了,规则就是「写了不生效」。历史缺口「面包屑 `visible:false` 写了 `display:none` 却照旧显示」「页签关闭钮 `opacity` 写了却仍要 hover 才显」全部源于此——两条规则本身都没写错,是**赢了才是硬道理**这一步没人做。
9
+ 第 1 步输出的 `▸ 覆写优先级 priority` **不是提示,是落地写法的硬要求**。每落一条规则前先按策略决定写法;写法错了,规则就是「写了不生效」——如面包屑 `visible:false` 写成 `display:none` 却照旧显示、页签关闭钮 `opacity` 写了却仍要 hover 才显。这类情形里两条规则本身都没写错,问题出在**赢了才是硬道理**这一步没做。
10
10
 
11
11
  | `priority.strategy` | 对手 | 必须的写法 | 自检判据 |
12
12
  |---|---|---|---|
@@ -9,7 +9,7 @@
9
9
  跑 `code-quality` 全量清单之外,追加:
10
10
 
11
11
  - [ ] 变更集外的任何点位**零改动**(diff 只含变更集提到的文件/选择器)
12
- - [ ] **页面清单零增量(G13 页面绑定闸 · 历史事故:效果图演示页「运单管理」被误落地为项目新菜单)**:diff 中不得出现新增的路由定义 / 菜单项 / 页面文件,除非变更集 `page_bindings` 显式声明 `target:"new"` 且 `notes` 已申报。效果图页面默认是设计角色坐标系(演示标题),落地 = 映射已有页面同步结构与样式;`page_bindings` 缺省时本项必须为零增量。验收只比「结构与样式」,不比「页面标题文字」
12
+ - [ ] **页面清单零增量(G13 页面绑定闸)**:diff 中不得出现新增的路由定义 / 菜单项 / 页面文件,除非变更集 `page_bindings` 显式声明 `target:"new"` 且 `notes` 已申报。效果图页面默认是设计角色坐标系(演示标题),落地 = 映射已有页面同步结构与样式;`page_bindings` 缺省时本项必须为零增量。验收只比「结构与样式」,不比「页面标题文字」
13
13
  - [ ] `visible: false` 的模块代码仍存在(只是隐藏)
14
14
  - [ ] **`!important` 使用合规**:新增 `!important` 仅允许两种情形——① 词典 `priority.strategy = self_plus_important`(对手带 `!important`);② 对手为组件 scoped 且提权后**实测**仍平手;且每条带理由注释。其余一律靠作用域限定解决。无内联 style 硬编码色值(全部走变量)
15
15
  - [ ] 未修改 `src/components/`(Re* 组件库源码——**底线一**)
@@ -33,11 +33,23 @@
33
33
  - `content` ref 仍绑在定高容器上(换容器后未丢),`otherRef` 仍在表格上方、分页仍在表格正下方;
34
34
  - 表头 / 行 / 分页都在视口内,仅表格体内滚动,无外层滚动条、无拉伸 / 塌陷 / 双滚动条,`tableHeight > 0`;
35
35
  - **结构层 diff 为空**:`lay-content/index.vue` 的 `.main-content[data-content-mode]` 与 `element-plus.scss` 的 `[data-fill]` 未被改动;同时确认没有「为保高度而放弃设计还原」(出厂卡片 / 内边距 / 内部排布原样未动而变更集声明了改动)——两个方向任一命中即返工
36
- - [ ] **映射通道活性检查(杂必查)**:样式落地引用的每个 CSS 变量必须在项目样式中**存在消费者**(`变量名` 有 `var(--xxx)` 引用点);只定义不消费的变量 = 通道死路,翻译再准也不生效(menu_active_indicator 曾因 --vts-theme-menu-active-before 无消费者而「映射了却没效果」)。施工时 grep 核对,无消费者时改走消费者存在的作用域或补挂载点并申报。
37
- - [ ] **结构施工兑现检查(structure_ops 逐条对账,与红线同级)**:变更集 `structure_ops[]` 的**每一条 op** 都必须在交付说明给出「op → 落在哪个文件 / 哪个节点 / 怎么落的」;`add_node` 必须真的新增了元素或渲染分支(模板 diff 可验),`bind_source` 必须真的改了绑定(`class-name` / `align` / `formatter`)。出现「声明了 op、代码里找不到对应改动」= 交付不完整,禁止只改 CSS 冒充结构施工(历史缺口:操作列分割线 `add_node` 声明了但从未施工 → 按钮间竖线一直缺失)
38
- - [ ] **同权重失效检查( · 专查「写了不生效」)**:逐条核对设计层新增规则是否真能取胜——① 对手是组件 `<style scoped>` 时,本条特异度必须**严格高于**它(**平手即错**,因为组件样式在全局之后注入);② 对手带 `!important` 时本条必须同样 `!important`,或改走通道变量。**判定方法(必须真数,不许目测)**:对每条新规则与其对手分别写出特异度三元组 `(a,b,c)` 并**逐位比较(先 b 后 c)**,本条的 `b` 不大于对手即判为「失效」;`html` / `body` 只加 `c` 位,**对手 `b` 更高时加 `html body` 无效**,必须靠**加类**(祖先链补稳定语义类,如 `.el-menu`)把 `b` 抬到相等。同 `b` 时,`c` 更高者胜。③ **出厂用语义令牌间接设置该属性时(`var(--vts-theme-*)`),必须先走「令牌重映射」而不是抢属性**——在令牌宿主作用域重声明令牌即生效、零权重战争;只有无令牌或令牌语义不符时才抢属性。历史缺口全部命中本项:面包屑 `display:none`(与组件 scoped 同为 0,2,0)→ 照旧显示;页签关闭钮 `opacity`(同为 0,5,0)→ 仍要 hover 才显;页签项 `padding`(对手带 `!important`)→ 无论怎么抬特异度都改不动;**侧栏菜单 `color`(`b=2` 输给出厂 `b=3` + `!important`)→ 整栏菜单文字用浅色主题的黑色落在深色侧栏上、字全部消失**
36
+ - [ ] **映射通道活性检查(杂必查)**:样式落地引用的每个 CSS 变量必须在项目样式中**存在消费者**(`变量名` 有 `var(--xxx)` 引用点);只定义不消费的变量 = 通道死路,翻译再准也不生效(例如 menu_active_indicator 缺 `--vts-theme-menu-active-before` 消费者时会「映射了却没效果」)。施工时 grep 核对,无消费者时改走消费者存在的作用域或补挂载点并申报。
37
+ - [ ] **结构施工兑现检查(structure_ops 逐条对账,与红线同级)**:变更集 `structure_ops[]` 的**每一条 op** 都必须在交付说明给出「op → 落在哪个文件 / 哪个节点 / 怎么落的」;`add_node` 必须真的新增了元素或渲染分支(模板 diff 可验),`bind_source` 必须真的改了绑定(`class-name` / `align` / `formatter`)。出现「声明了 op、代码里找不到对应改动」= 交付不完整,禁止只改 CSS 冒充结构施工
38
+ - [ ] **同权重失效检查( · 专查「写了不生效」)**:逐条核对设计层新增规则是否真能取胜——① 对手是组件 `<style scoped>` 时,本条特异度必须**严格高于**它(**平手即错**,因为组件样式在全局之后注入);② 对手带 `!important` 时本条必须同样 `!important`,或改走通道变量。**判定方法(必须真数,不许目测)**:对每条新规则与其对手分别写出特异度三元组 `(a,b,c)` 并**逐位比较(先 b 后 c)**,本条的 `b` 不大于对手即判为「失效」;`html` / `body` 只加 `c` 位,**对手 `b` 更高时加 `html body` 无效**,必须靠**加类**(祖先链补稳定语义类,如 `.el-menu`)把 `b` 抬到相等。同 `b` 时,`c` 更高者胜。③ **出厂用语义令牌间接设置该属性时(`var(--vts-theme-*)`),必须先走「令牌重映射」而不是抢属性**——在令牌宿主作用域重声明令牌即生效、零权重战争;只有无令牌或令牌语义不符时才抢属性。典型失效例:面包屑 `display:none`(与组件 scoped 同为 0,2,0)→ 照旧显示;页签关闭钮 `opacity`(同为 0,5,0)→ 仍要 hover 才显;页签项 `padding`(对手带 `!important`)→ 无论怎么抬特异度都改不动;**侧栏菜单 `color`(`b=2` 输给出厂 `b=3` + `!important`)→ 整栏菜单文字用浅色主题的黑色落在深色侧栏上、字全部消失**
39
39
  - [ ] **oracle 基线可用性检查**:变更集带 `oracle` 时——① `oracle.mockup` 必须与**本次主题、本次页面**一致;**同构异色复用除外**:变更集声明 `oracle.theme_mapping: { "from": "<效果图主题>", "to": "<本次主题>" }`(同场景 / 同页面 / 同角色集合、仅主题色板不同)时,允许复用 from 主题效果图,verify 必须带 `--from-theme/--to-theme` 做色值归一,**不得因换主题色就判死闭环**;结构 / 形态有差异时禁止复用;② `oracle.sids` 与 `changes[]` **双向闭合**:效果图里有、changes[] 未声明 = **欠声明**(该点位永远不可能被还原);changes[] 已声明、效果图无 sid = **无基线**——**仅 `visible:false` 的隐藏点位豁免**(效果图上无可见元素可标 `data-sid`,parser 已自动豁免并打印清单)。其余两类出现即回流设计侧补齐,**不得直接开工**(`parser match` 已自动报出);③ **状态性期望与孤儿对账(G14/G15,抽取产物层)**:效果图上有可见状态性表现的点位(禁用置灰 / 激活 / 选中)→ `oracle.json.states` 必须有对应 `<sid>@<state>` 期望(缺失 = 状态维度放弃验收);交付前核对项目页渲染的每个区块都在 oracle 全集(sids ∪ absent ∪ residual ∪ states)内——孤儿点位 verify 当场 exit 1,提前自查可省一轮返工
40
- - [ ] **dark.scss 暗色同步**:新增视觉规则在 `html.dark` 有对应覆盖
40
+ - [ ] **设计层闭环审计闸(机器断言,ERROR 必须清零)**:施工完成后跑 `node scripts/design-audit.mjs --project <落地项目> --container-width <内容区实际宽>`,或 `VUE3_AUDIT_PROJECT=<落地项目> npm run check`。本闸把「声明了 ≠ 生效」拆成逐条静态断言,替代肉眼目视,任一 ERROR 即视为未交付。**与 `parser/index.js audit` 的分工**:parser audit 管「通道与挂载点」(selector 有没有挂载点、变量有没有消费者),本闸管「生效性与形态」(层路由、层叠胜负、列宽预算、收口断言、形态成对);E1/E4 是两者的故意重叠项,用作交叉校验:
41
+ - E1 变量悬空 → 使用了项目内无定义且无 `var()` 回退的自有变量,整条声明失效
42
+ - E2 层错位 → 内层盒属性族(`white-space` / `text-overflow` / `overflow` / `text-align` / `line-height` / `vertical-align` / `word-break`)写在表格宿主盒 `th/td.el-table__cell` 上而非 `> .cell`,会被 Element Plus 内层 `.cell` 覆盖
43
+ - E3 **层叠败北** → 本条声明的作用元素上的特异度 ≤ 组件 scoped 竞争者的实际特异度(scoped 编译会给末位选择器追加 `[data-v]`,等价 +1 类级;平手判负,因为组件样式晚于全局注入)
44
+ - E4 选择器挂空 → 设计层使用的项目类名在 `src/` 无挂载点(锚点必须锚「实际在」)
45
+ - E5 **列宽预算** → 存在既无 `width` 又无 `min-width` 的业务列;或 `min-width` 小于该列表头文案的最小占宽;或列宽合计溢出容器而未见滚动策略
46
+ - E6 收口断言 → 变更集 `visible:false` 的点位必须在设计层找到「命中该锚点且 `display:none !important`」的落点
47
+ - E7 激活态越层 → 激活胶囊/指示条写到了可展开分组的标题上(`.el-sub-menu__title` 须显式排除)
48
+ - E8 浮层残留 → 声明收口下拉浮层的 form,组件却仍保留 `ElDropdown` / `#dropdown` 消费(teleport 浮层样式层收不掉,必须结构收口)
49
+ - E9 形态收口缺件 → `icon_only` 只落了「显图标」而没有**在同一作用域内**收口文案(作用域外的兄弟变体收口不算成对)
50
+ - E10 scoped 挂空 → 组件 scoped 规则依赖运行时并不存在的类(结构重构后残留,永不命中)
51
+ - [ ] **列宽由表头文案反推(E5 落地口径)**:每个业务列(含选择列、序号列)都要显式声明 `width` 或 `min-width`,取值 ≥ 该列表头文案宽度 + 左右各 16px 内边距(CJK 按 1em、ASCII 按 0.6em 估)。无宽列只能拿出厂兜底宽度参与布局,会被相邻固定宽列挤压——**表头换行与省略号截断的唯一根因就在这里**,不接受「跑起来看着还行」
52
+
41
53
  - [ ] **缺口清单只含意图缺口**:清单每一项都必须是「设计侧未给值 / 值非法」且已注明「回流设计侧补齐」;能力缺口(词典缺 ID / 缺字段枚举 / 缺 form)不得出现在清单里——出现即把可落地项搁置
42
54
  - [ ] **台账逐行兑现对账(对账闸门)**:把设计侧交付的提取台账逐行过一遍,每行必须有落地结论——已落地(写明落在哪个文件/选择器)或已入缺口清单(写明缺失字段)。存在「台账有行、落地无结论」的行 = 交付不完整,与红线同级
43
55
  - [ ] **登记表覆盖率对账(子项级细闸,)**:带登记表交付时必须跑 `match --registry`——`C = A` 且无缺口才可交付;同时确认无「效果图标注缺口」(`always:true` 子项在效果图上都有同名 `data-sid`)。**禁止采信设计侧自报的 `coverage` 数字**(parser 会当场重算,自报数不参与);缺口逐条点名回流设计侧
@@ -33,11 +33,11 @@
33
33
  | **选择器落空** | oracle 有点位、actual 无(或某属性取不到) | 补挂载点:按 `structure_ops` 挂类 / 补 `data-sid` / 确认元素已渲染(属能力缺口,交付说明申报) |
34
34
  | **权重被压** | 颜色 / 字重 / 透明度 / 阴影类属性值不符 | 按词典 `priority` 声明的策略提权(`scope_qualified` / `self_plus_important` / `deep_qualified`) |
35
35
  | **语境错位** | 几何 / 盒模型属性(padding / 尺寸 / 对齐 / 行高)值不符 | 校准 `layer`(`host` vs `inner`)——值对了落错层 |
36
- | **存在性缺口(G12)** | `oracle.absent` 点位在页面仍渲染可见(`display` 非 `none`) | 补 `visible:false` 收口并按词典 `priority` 提权(历史缺口:面包屑 `display:none` 被同权重 scoped 规则反压——写了不生效也是它) |
37
- | **状态缺口(G14)** | `oracle.states` 的 `<sid>@<state>` 交互态期望与实测不符 / 实测未取到 | 浏览器脚本**触发交互态**(`.click()` / `hover()` / `dispatchEvent`)后抽取到 `actual.states` 同名键;禁用态走结构通道(`disabled` 属性 / `:disabled` 类)+ 设计层样式(历史缺口:效果图「批量按钮置灰 opacity:.4」在静态快照上永远取不到——页面静态抽的是激活态值,逐点 diff 验不到,2026-09-22 机制化) |
36
+ | **存在性缺口(G12)** | `oracle.absent` 点位在页面仍渲染可见(`display` 非 `none`) | 补 `visible:false` 收口并按词典 `priority` 提权(面包屑 `display:none` 被同权重 scoped 规则反压即属此类——写了不生效) |
37
+ | **状态缺口(G14)** | `oracle.states` 的 `<sid>@<state>` 交互态期望与实测不符 / 实测未取到 | 浏览器脚本**触发交互态**(`.click()` / `hover()` / `dispatchEvent`)后抽取到 `actual.states` 同名键;禁用态走结构通道(`disabled` 属性 / `:disabled` 类)+ 设计层样式(如效果图「批量按钮置灰 opacity:.4」在静态快照上取不到——页面静态抽的是激活态值,逐点 diff 验不到) |
38
38
  | **孤儿点位(G15)** | actual 中存在、oracle 全集(sids ∪ absent ∪ residual ∪ states)均无申报 | 两选一回流设计侧:应消失 → 收进 `oracle.absent`;该还原 → 补 `oracle.sids` + 效果图 `data-sid`。**G12 只断言「已申报的该消失」,孤儿闸补齐「未申报的出现了」——申报缺一个 = 漏网一个** |
39
39
 
40
- **存在性闸(`oracle.absent`)**:效果图上不存在的出厂点位(面包屑 / 设置铃铛等)逐条列入变更集 `oracle.absent`,verify 逐个断言「actual 不存在或 `display:none` / `visibility:hidden`」。**这类缺口无期望值,逐点 diff 永远验不到——不进 absent 就不在验收范围内**(2026-09-21 面包屑事故机制化)。
40
+ **存在性闸(`oracle.absent`)**:效果图上不存在的出厂点位(面包屑 / 设置铃铛等)逐条列入变更集 `oracle.absent`,verify 逐个断言「actual 不存在或 `display:none` / `visibility:hidden`」。**这类缺口无期望值,逐点 diff 永远验不到——不进 absent 就不在验收范围内**。
41
41
 
42
42
  **状态断言闸(`oracle.states`,G14)**:交互态(disabled / active / hover / focus / checked)在静态页面快照上取不到——效果图标注的状态性样式(批量按钮禁用置灰、页签激活字重)与页面静态抽取值**永远对不上或永远碰巧对上**,逐点 diff 均验不到。设计侧在 `oracle.json` 顶层声明:
43
43
 
@@ -54,7 +54,7 @@
54
54
 
55
55
  **孤儿点位对账闸(G15)**:verify 自动对账 actual 顶层点位与 oracle 全集(`sids ∪ absent ∪ residual_accepted ∪ states` 的 sid 部分),**未申报即出现 = 孤儿,exit 1**——效果图是验收的完备性基准,「图上没有、清单也没说」的页面元素不允许静默存活(它是下一轮「图上怎么多了个东西」体感的来源)。结构性键(`$` 前缀注释 / `sids` / `states`)不参与对账。
56
56
 
57
- **残差豁免(`oracle.residual_accepted`)**:`[{ "sid": …, "reason": … }]`(reason 必填)。命中豁免的属性差异降级为「已申报固有残差」提示行,不进缺口计数;验收报告单列豁免明细,逐条可审计。**机制推算值(等宽槽宽)、业务资产(logo 图形)必须申报**——不申报 = 每轮验收重新报缺口 = 「改了很多版始终不行」的体感来源。
57
+ **残差豁免(`oracle.residual_accepted`)**:`[{ "sid": …, "reason": … }]`(reason 必填)。命中豁免的属性差异降级为「已申报固有残差」提示行,不进缺口计数;验收报告单列豁免明细,逐条可审计。**机制推算值(等宽槽宽)、业务资产(logo 图形)必须申报**——不申报 = 每轮验收重新报缺口 = 「反复调整仍无改善」的体感来源。
58
58
 
59
59
  **快照回归(`--snapshot` / `--baseline`,治「上一轮改对的这一轮漂回」)**:
60
60
 
@@ -71,5 +71,7 @@ node parser/index.js verify --oracle oracle.json --actual actual.json --baseline
71
71
  **夹具与设计资产的边界(职责单侧沉淀红线)**:`「页面名-主题」`命名法(如 `运单管理-钴蓝.html`)是设计侧效果图库的专属资产命名——**项目侧(含 parser/fixtures 回归夹具)禁止出现与设计侧资产同名的文件**。回归需要 mockup 实物时,一律用「回归夹具-」前缀合成名(如 `回归夹具-列表页-钴蓝.html`),点集为回归机制定制、与真基线**不同且不可互替**;真实效果图基线唯一沉淀在设计侧 `page-specs/styles/<方案>/scenes/<场景>/mockups/`,项目侧 `oracle.mockup` 指向它靠 `resolveFirstExisting` 跨库解析(变更集同目录 → cwd → 技能根 → 设计侧兄弟目录),不做本地拷贝。
72
72
 
73
73
  - 验收结果写入最终回复(命中 N / 缺口 M / 归因分布 / 修正)与 `code-quality` 结果块;**不得只报「已完成」**。
74
+ - **入场前置:闭环审计闸必须已清零**。`node scripts/design-audit.mjs --project <落地项目> --container-width <内容区实际宽>` 存在 ERROR 时不得进入渲染态验收——层错位 / 层叠败北 / 无宽列这类失效会让 verify 侧出现「期望值取不到」或「值对但不生效」的假缺口,先修闸门再比对,否则每轮都在给同一个根因换皮。
74
75
  - 变更集无 `oracle` 时输出 `N/A`(无基线),并在交付说明注明「无验收基线」——这是设计侧应补的项,回流设计侧。
75
76
  - 静态审计(audit)与渲染态验收(verify)**互补**:audit 查「通道是否存在」,verify 查「渲染结果是否一致」,两者都过才算闭环。
77
+ - **三闸自洽口径(无 oracle 时也不放行)**:`mapping coverage` 全绿只证明「点位被覆盖」,`parser audit` 全绿只证明「通道与挂载点存在」,`design-audit` 全绿只证明「声明具备生效条件」——三者都不证明「渲染结果与效果图一致」。缺 `oracle` 的批次必须显式声明「本轮无渲染态基线」,不得用前两闸的绿灯冒充闭环。
package/scripts/check.mjs CHANGED
@@ -10,6 +10,7 @@
10
10
  */
11
11
 
12
12
  import { execFileSync } from "child_process";
13
+ import fs from "fs";
13
14
  import path from "path";
14
15
  import { fileURLToPath } from "url";
15
16
 
@@ -19,6 +20,15 @@ const NODE = process.execPath;
19
20
  const PYTHON = process.env.VUE3_SKILL_PYTHON || (process.platform === "win32" ? "py" : "python3");
20
21
  const PYTHON_ARGS = process.platform === "win32" && !process.env.VUE3_SKILL_PYTHON ? ["-3"] : [];
21
22
 
23
+ /** 设计层闭环审计的目标项目:默认当前目录,可用 VUE3_AUDIT_PROJECT 指向落地项目 */
24
+ function resolveAuditProject() {
25
+ const dir = process.env.VUE3_AUDIT_PROJECT || process.cwd();
26
+ const designDir = path.join(dir, ".codebuddy", "design");
27
+ if (!fs.existsSync(designDir)) return null;
28
+ const has = fs.readdirSync(designDir).some((f) => /^changeset.*\.json$/i.test(f));
29
+ return has ? dir : null;
30
+ }
31
+
22
32
  const checks = [
23
33
  {
24
34
  name: "结构校验",
@@ -30,6 +40,19 @@ const checks = [
30
40
  desc: "高频 Demo 场景能力组命中验证",
31
41
  cmd: () => run("python", "scripts/match.py", ["--batch"]),
32
42
  },
43
+ {
44
+ name: "设计层闭环审计",
45
+ desc: "变量悬空/层错位/层叠胜负/锚点挂空/列宽预算/收口断言(无落地项目则跳过)",
46
+ cmd: () => {
47
+ const project = resolveAuditProject();
48
+ if (!project) return "SKIPPED 未发现落地项目(.codebuddy/design/changeset*.json);用 VUE3_AUDIT_PROJECT=<落地项目> 指定后复跑";
49
+ const args = ["--project", project];
50
+ if (process.env.VUE3_AUDIT_CONTAINER_WIDTH) {
51
+ args.push("--container-width", process.env.VUE3_AUDIT_CONTAINER_WIDTH);
52
+ }
53
+ return run(NODE, "scripts/design-audit.mjs", args);
54
+ },
55
+ },
33
56
  ];
34
57
 
35
58
  function run(runner, script, args = []) {