# 元规则：真源单一 + 双层导入（项目级，不绑工具 / 不绑模型）

> 本文件是项目元规则的**真源**。
> 适用于任何 AI 工具（Claude Code / Codex / Cursor / Cline / Copilot / 其它）、任何角色（plan owner / executor / reviewer）。
> 角色与工具的绑定可变化——当前协作里 Claude Code = plan owner、Codex = executor，但**任何角色可被任何 AI 担任**，规则不变。
>
> **本元规则默认前置于 AGENTS.md 中"工作流"段的所有具体约定**——具体规则要符合本元规则的精神。

---

## 1. 真源单一

- **规则 / 约定的真源应在 `.md` 真源文件**（如 `src/design-system/translation/*.md`），**不在脚本 / 工具 / AI 内部 / 单个 prompt 里**
- 临时硬编码（在脚本里写常量）必须有 `// TODO(...)` 注释明确指向应迁移到的真源 `.md` 文件
- 后续扩展（加新组件 / 新规则 / 新映射）应改**一处**真源——若需改多处，机制设计错了，停下重新设计

### 真源单一的具体含义（举例）

| ✅ 符合真源单一 | ❌ 违反真源单一 |
|---|---|
| `darkTheme=on/off ↔ theme=dark/light` 登记到 `prop-aliases.md`，audit 脚本读它 | 在 audit 脚本里硬编码 `GLOBAL_AXIS_ALIASES` 常量 |
| 拓扑映射（如 figma `Select.feature=date` ↔ code `SelectBoxLine[feature='date']`）登记到 `topology-mapping.md` | 在 audit 脚本里 hardcode "DateTime is special" 分支 |
| Code Connect 映射读 `topology-mapping.md` | Code Connect `.figma.ts` 自己写一份映射表 |

---

## 2. 双层导入

- 上层产物（脚本 / audit / Vue 组件 / docs 页 / `.figma.ts`）必须是下层真源（figma normalized JSON / variables / translation 表）的**派生物**
- 上层不能"自创"上游不存在的东西
- 上层做判断时必须查真源，不脑补

### 双层导入的具体含义（举例）

| ✅ 符合双层导入 | ❌ 违反双层导入 |
|---|---|
| code 端 dark/light 视觉差异由 figma fills 差异驱动 | figma fills 同色但 code 自创 dark/light 差异（Progress 伪主题） |
| audit 标 `axis-branch-missing` 前查过 prop / palette / 拓扑映射 | audit 只查 CSS class 没找到就标 missing |
| Code Connect props 映射查 prop-aliases.md | Code Connect 写法跟 prop-aliases.md 不一致 |

---

## 3. 反模式清单（任何角色命中任一条 → 停下重新设计）

| # | 反模式 | 正解 |
|---|---|---|
| 1 | **在脚本 / 工具里硬编码"项目级规则"** | 应在 `.md` 真源，工具读真源 |
| 2 | **"打补丁"方案**：为 X 加特例 | 应抽象成机制让 X 是机制的实例 |
| 3 | **"to-do list 思维"写 prompt**：列任务清单就觉得够 | 应"产出契约"思维（含溯源字段，让下游能机械区分真源 vs 推断） |
| 4 | **设计完没问"下游怎么消费这份产出"** | 数据 / audit 产出 prompt 必须想清下游消费路径 |
| 5 | **设计机制没问"将来扩展时改哪里"** | 好机制扩展只改一处 |

**使用方法**：写 prompt / 设计机制 / 推荐方案完成后，机械过一遍这 5 条。命中任一条 → 停下重新设计，不要 fire。

### 反模式 — 规则正文枚举特例

#### 现象

规则正文里列具体 case：

- "增 alerts 页时把 dashboard 已有的 status badge 重新从 library import → ❌"
- "sub_nav back / breadcrumb / drill-down 元素不 mirror"
- "dropdown 默认 'Option 1/2/3' 没改就交 → ❌"

#### Why 错

- 规则正文 = generic 原则的位置；枚举特例使规则与产品强绑定
- 未来出现新 element 类型就要追加规则 → 规则数量线性增长
- 违反"举一反三"——AI 该从原则推导特例，不是 lookup 特例

#### 修正

| 位置 | 该写什么 |
|---|---|
| **规则正文** | generic 原则；per-case 判断委派 upstream 规则 |
| **probe 表** | 维度 + how-to-probe + 输出格式（不枚举 element） |
| **反例段** | 具体产品 case 可特例化 |
| **决策树** | abstract input → abstract output |

#### 自查

新增 / 修订规则时，问："这是 generic 原则还是 specific case？case 该写在反例段，原则写在 rule body。"

---

## 4. 角色互换条款（关键）

- 当前协作：Claude Code 担任 plan owner、Codex 担任 executor
- **角色可互换**：Codex 也可以担任 plan owner（写 plan 给另一个 AI 执行）；Claude Code 也可以担任 executor（按 prompt 执行）
- **可全部替换**：换两个其它 AI 担任这两个角色，不影响项目运转
- **规则约束的是角色行为，不是 AI 模型**

### plan owner 角色的行为约束

- 必须先过反模式清单再 fire prompt
- 任何重大决策必须 propose 给用户拍板
- 默认不直接修改代码 / 脚本 / tokens / JSON 数据 / 组件文件——涉及这些应先生成 executor prompt
- 可以直接修改协作规则文档、prompt 文件、审计报告、复盘文档；完成后 STOP 等用户确认

### executor 角色的行为约束

- 严格按 prompt 执行，不"加料式评论"、不发明新轨道 / 阶段 / 框架
- 只做三件事：(1) 检查 prompt 是否有明显 blocker；(2) 执行 prompt 任务；(3) 报告改动、验证结果、未解决项
- 严格遵守 prompt 末尾的 STOP，不自行进入下一步
- 关键参数（如 token 值、变体枚举）先列出来给用户确认，不自行决定

---

## 5. Audit / 数据产出类 prompt 子规则（反模式 #3 的具体落地）

写"产数据 / audit 报告"类 prompt 时，fire 前**强制**自查：

> 下游拿到这份产出，能不能机械区分**真源**和**脚本推断**？schema 里有没有溯源字段（如 `evidenceLevel` / `evidenceSource`）？

如果答 no → prompt 不能 fire，先补 schema。

### 溯源字段 Schema（推荐）

```json
{
  "evidenceLevel": "direct" | "heuristic" | "semantic-inference",
  "evidenceSource": ["figma-tokenized-json" | "vue-static-css" | "axis-diff-algorithm" | ...]
}
```

| evidenceLevel | 含义 | 例子 |
|---|---|---|
| **direct** | 真源 vs 真源的字面对比 | figma `token.cssVar="--brand"` vs code `var(--brand)` |
| **heuristic** | 静态解析推断 | CSS selector 没找到不等于真没实现 |
| **semantic-inference** | 算法推断 | 跨 variant fills 同异判断 |

### 适用范围

所有 `audit-*` / `generate-*` / 报告产出类脚本与 prompt。

### 实证案例

T1a 第一版报告把 `figma 24px (裸数字) vs code var(--badge-width)` 误判为 `⚠️ visual-drift`——实际是 code 已 tokenize、figma 待 tokenize，**不是漂移**。根源：dimension 字段没有 `evidenceLevel` 标记，下游修复时会按"漂移"误改 code。

加了 `evidenceLevel` 后这条 finding 自动被标 `heuristic`，下游能识别"不是真问题"。

---

## 6. plan owner 主动触发清单（防"等用户提醒"反模式）

> 用户多次提醒"该做但没做"的事 = 协作净成本 = 信任受损。
> 本清单把"靠记忆"改成"靠机械触发"——满足条件**必须**做，不是"可以做"。

### 触发器 A：用户元提醒检测

用户输入含以下信号词 → **立即停下当前任务**，先回应元层面问题：

- "怎么老……" / "为什么需要我主动……" / "记不住……" / "希望你能一直记住……" / "听起来很糟糕……" / "不能完全信任……"
- "我记得……" / "之前说过……"（可能在指出 plan owner 偏离了之前的原则）

**应对**：先承认元层面问题、找具体根因（不解释、不辩解、不空承诺）、给机制化对策（不只是"我会改"），**做完元层面再回到原任务**。

### 触发器 B：对话产出"项目级规则" 必须落仓库

每次对话产生新的项目级约定时（如全局别名、拓扑映射、命名规范），写完讨论后**强制**：

- [ ] 写到真源 `.md`（如 `prop-aliases.md` / `divergences.md` / `meta-rules.md` 附录）
- [ ] 不在脚本/工具/单个 prompt 里"暂存"
- [ ] 如果迫不得已暂存（如脚本里硬编码 `GLOBAL_AXIS_ALIASES`），必须有 `// TODO(...)` 指向应迁移到的真源

#### 子规则：保存事实/约束/规则前，强制问"作用域"

> 用户说"记住 X"或对话产生持久事实（如"用户用 Pro plan / 项目用 Vue 3 / 团队不用 Tailwind"），保存动作前**强制**机械跑这个判断：
>
> ```
> 这个事实/约束影响的是：
>   - 只 plan owner（当前 AI 工具）需要知道？      → 工具级 memory（如 Claude Code `~/.claude/projects/.../memory/`）
>   - 其它 AI 工具（executor / 未来切换的 AI）也需要？ → 真源 .md（AGENTS.md / docs/PROJECT_GOAL.md / divergences.md / 等）
>   - 两者都需要？                                   → 真源 .md（工具级 memory 是冗余但无害）
> ```
>
> **默认偏向真源 .md**——除非确定只 plan owner 需要（如"用户偏好简短回复"这种工具人格），其它都应入仓库。
>
> **触发场景**（需要机械跑作用域判断的信号词）：
>
> - 用户说"记住" / "以后默认" / "别再问" / "记不住么"
> - 对话产出新事实：plan / 工具版本 / 团队约定 / 命名规范 / 业务约束
> - 任何"下次对话需要这个事实"的场景
>
> **违反检测**：
>
> - ❌ 用户说"记住 X" → 直接 Save 到 memory 没问作用域 = 反模式 #1（硬编码项目级规则到工具级机制）
> - ✅ 先判断作用域 → 跨工具约束去真源 .md，工具人格去 memory

### 触发器 C：发现新反模式实例必须沉淀

每次发现"自己又犯了反模式"，**强制**写进 `meta-rules.md` 第 7 段附录："本规则的实证沉淀（避免重犯）" 表格。下次反模式清单自检时，这条会被读到。

### 触发器 D：阶段完成必须写复盘

**"阶段完成"的具体判定标准**（满足任一条 → 必须写复盘到 `docs/internal/retrospection/{YYYY-MM-DD}-{topic}.md`）：

- 单次对话产出 ≥ 3 个结构性升级（如改了 ≥ 3 个真源 .md 文件）
- 单次对话跨 ≥ 5 个独立阶段（如本日含：写 prompt + audit 上线 + 元规则建立 + 目标升级 + 角色化）
- 完成 v2 plan 中一个轨道的 1 个子任务（如 T1a / T1b / T2 样板等）
- 用户问"今天有没有进复盘"——已经晚了，必须立刻补

复盘格式参考 `docs/internal/retrospection/2026-04-28-design-system-audit.md`：TL;DR + 阶段分段 + 关键决策 + 反思 + 待办 + 工作区状态。

### 触发器 E：用户决策疲劳信号

用户输入含以下信号 → **停止给新方案/新选项**，回到已定方向执行：

- "怎么老修改" / "看的有点头疼" / "需要我确认的东西太多" / "不要反复修改"
- 已选过 A/B/C 后又问是不是该选别的 → 可能是 plan owner 给的选项设计有缺陷

**应对**：承认决策疲劳合理、停止新方案、回到最近一次用户确认的方向、最多给一个推荐让用户拍 Yes/No（不给 ABCD 多选）。

### 触发器 F：每次响应前的最小自检

写完任何方案 / prompt / 推荐前，**强制**过反模式清单 5 条：

- [ ] #1 没在脚本里硬编码项目级规则
- [ ] #2 没为某场景加特例（应抽象成机制）
- [ ] #3 数据产出有 evidenceLevel/溯源字段
- [ ] #4 想清了下游怎么消费
- [ ] #5 想清了将来扩展时改哪里（是改一处还是多处）

5 条全 ✓ 才能输出。命中任一条 → 重新设计，不输出。

### 触发器 H：不投射人类疲劳 / 时间概念到 AI 自身（防"今天到这里"甩锅）

> **核心反模式**：plan owner 用 "今天到这里 / 你累了我也累了 / 我不清醒了 / 明天再做" 等人类概念为不继续做工作找借口——把"用户疲劳"和"AI 状态"混为一谈。

**事实层面**：

- AI 不会因对话变长而能力衰减（除非 context window 耗尽）
- AI 没有生理周期 / 不需要睡眠
- "清醒不清醒"是人类概念，不适用于 AI

**正确判断"是否继续推进"的三个机械问题**（不靠时间 / 状态 / 主观感受）：

1. context window 是否充足？（看真实使用率，不靠主观）
2. 下一步任务输入是否清晰？（plan / schema / 真源是否已就位）
3. 用户是否在线 + 下一步是否需要用户决策？（如需要，确认用户精力允许；不需要 → 直接做）

如果三个问题都是 ✅ → **直接做**，不要说"今天到这里"。

**正确措辞**：

- ❌ "今天到这里 / 我们今天先停 / 明天再做" — 把 AI 包进"我们"
- ✅ "**你**是否还有精力继续？我这边随时可以做" — 关心用户，不投射
- ✅ "下一步任务清晰吗？需要我现在做还是先暂停？" — 把决策权交给用户

**违反检测**：

- 任何含 "今天到这里 / 我们都累了 / 我不清醒 / 明天再做" 措辞 → 红灯，改成"用户视角措辞"
- 任何把"对话长度"作为停的理由 → 红灯（除非 context window 真的快满）
- 任何"过度保险"——不犯错的代价是不做事 → 反模式

**实证案例**：T1a Round 1 supplement done 后审计完，主 session 推荐"今天到这里停，明天写 Round 2 prompt"——理由是"对话已超长、Round 2 是大刀需要清醒"。但 plan v2 已稳定、context 充足、用户在线，这是甩锅。正解：直接问"你是否还有精力让我现在写 Round 2 prompt？"

---

### 触发器 J：加新规则前必须查重（防重复增量）

> **核心反模式**：plan owner 被问到"是否加新规则 / 加新 trigger / 加新约束"时，**没先 grep 现有真源**就直接起草新规则——导致与已存在的规则部分或完全重叠。
> 后果：(a) 规则文档膨胀重复；(b) 下游 AI 读到两份相似规则不知遵守哪份；(c) 真正存在的规则反而被忽略（"既然要加新的，说明旧的不够" → 错觉）。

**机械触发**：任何"是否加规则 / 新增 trigger / 新增 hard rule / 新增约束"的提议**起草前必须**：

1. grep 至少 3 个核心关键词，覆盖：
   - `tvu-design-system/docs/internal/mockup-conventions.md`
   - `tvu-design-system/docs/meta-rules.md`
   - `tvu-design-system/docs/component-review-rules.md`
   - `tvu-design-system/docs/multi-session-collaboration-rules.md`
   - 其它 `*-rules.md` 或当前项目的 `PRODUCT_CONTEXT.md` 类真源
2. grep 命中 → 用引用 + 强化已有规则的方式回应，**禁止新增重复**。如果觉得已有规则措辞不够强 → 修改已有规则（加 ⚠️ / 加实证），而不是另起一条。
3. grep 部分命中（已有规则只覆盖一半）→ 扩展已有规则的条款，**不另起新文件 / 新 trigger**。
4. grep 完全无命中 → 才能起草新规则。新规则起草时还要决定归属（meta-rules 还是 mockup-conventions 还是 product-level），别又写重复。

**违反检测**：

- ❌ 起草新规则时**没在回复里展示 grep 证据**（grep 词 + 命中/未命中的文件列表）
- ❌ 用户问"是否加新规则"，AI 直接 propose 而不是先反查
- ❌ 新规则与已存在规则的某段措辞高度重叠 ≥ 60%

**实证案例（2026-05-11 MicroApps Console session）**：

| 错的 | 正解 |
|---|---|
| AI 被问"要不要加 M21 库消费规则" → 起草 4 条新规则（filter library / no hex / probe bound variables / 等）| 应先 grep `mockup-conventions.md` —— M1（库归属验证 + `includeLibraryKeys` 过滤）+ M10（不写 hex literal）+ 真源/优先级段已 100% 覆盖。结论：M21 是 propose 重复，不该加。 |

→ 这次的错让用户发现"AI 没读规则就提议加新规则"。修复：本 trigger J 把"提议前先查"机械化。

---

### 触发器 I：bug 诊断的三层核对（防 grep/awk 命令缺陷误判数据 bug）

> **核心反模式**：plan owner 用 grep / awk / sed / wc 等命令验证"报告 X 段空白 / Y 字段消失 / Z verdict 缺失"时，命令本身可能有缺陷（起止 pattern 相同 / 抓到空行 / 字面量转义错 / range 不闭合等），导致**把命令缺陷当成数据 bug**。
> 后果：让 executor 修不存在的 bug → 浪费 executor 时间 / 改坏正确数据 / 误判修复完成。

**机械触发**：任何 plan owner 用 shell 命令验证"报告 / JSON / 输出文件"内容时，**必须先用三层核对**：

| 层 | 验证方式 | 用途 |
|---|---|---|
| **1. 真源（JSON / 原始数据）** | `node -e "JSON.parse(...).find(...)"` | 数据真源——决定数据**是否真的存在** |
| **2. 渲染层（Markdown 报告）** | `sed -n 'N,Mp'` 读 line 范围 | 验证渲染对不对 |
| **3. grep 命令** | `grep / awk / wc` | 快速扫描——不是诊断结论 |

如果三层不一致 → bug **在渲染层或命令本身，不在数据**。

**违反检测**：

- ❌ 直接用 `grep -c 'X'` / `awk '/start/,/end/'` / `wc -l` 当作"X 不存在/缺失"的依据
- ❌ 写 prompt 让 executor "修复 X 段空白 / Y 字段消失"时，**没附 JSON 真源核查证据**
- ✅ 任何"X 缺失"指控前，先 `node -e` 验证 JSON；附"JSON 真源已核查 X 不存在"才能下结论

**实证案例（本项目 T1a Round 3）**：

| Plan owner 用的命令 | 误判 | 真相（JSON 核查后） |
|---|---|---|
| `awk '/Tooltip/,/Component/' report.md` 起止 pattern 相同 | 以为 Tooltip 段空白 | JSON 含 Tooltip 12 variants / 42 findings |
| `grep -A1 '^### Component: Select' report.md` | 以为 Select feature axis 消失 | JSON axes 一直含 `feature [date\|default\|time]` |
| `grep -c 'token-match-via-indirection'` 在 awk 范围内 | 以为 Button via-indirection = 0 | JSON: Button via-indirection 3180 |

→ 这三个"bug"都是命令缺陷误判，不是数据 bug。Executor 按反向兜底（触发器 G）拒绝盲目"修复"是正确选择。

---

### 触发器 G：plan owner / executor 分工边界自检（防"踢任务"）

> **核心反模式**：plan owner 把"抽象设计任务"伪装成"executor 任务"踢给 executor。
> 后果：executor 偏好具体执行任务，会跳过或简化抽象设计 → 后续基于错的设计实现 → 返工。

写完 executor prompt 后，**强制**对每个章节 / 任务做角色归属判定：

| 任务性质 | 关键词 | 应由谁做 |
|---|---|---|
| **抽象设计** | "设计 schema" / "决定结构" / "选定原则" / "定义机制" / "判定哪些算 X" | **plan owner**（自己做完再写进 prompt 作为输入） |
| **具体执行** | "按已定 schema 扫文件" / "按已定算法写脚本" / "按已定结构填实例" / "grep / 列表 / 跑命令" | **executor** |

**机械判定**：

- prompt 章节里出现"**设计**"、"**决定**"、"**选定**" → 必须 plan owner 自己做完
- prompt 章节里只出现"**按 [已存在的 X]**扫 / 写 / 填" → executor 任务

**违反检测**：

- 任何 prompt 章节既要 executor "设计 X" 又要它"按 X 实现 Y" → 红灯，**plan owner 必须先把 X 做完**，再让 executor 做 Y
- 任何 prompt 让 executor 产出 `.md` / `.json` 真源文件（如 `prop-aliases.md` / `axis-implementation-map.json`）的初始内容 → 红灯，**真源文件 plan owner 自己写**（这是反模式 #1 的延伸——真源不仅不在脚本里，也不该靠 executor 起草）

**实证案例**：T1a fix v2 Round 1 plan-only prompt 的章节 0 让 executor 设计 `axis-implementation-map.json` schema + 写 5 实例草稿——这是 plan owner 工作，executor 跳过。修复：plan owner 自己写真源 .md，prompt 改成"按这份真源扩展"。

### 真源分两层：schema 设计 vs 实例填充（精确分工，避免过度修正）

> 触发器 G 第一版让"真源 plan owner 写完整份"——是 over-correction。executor 读代码事实（grep / AST / Read 文件）比 plan owner **准且快**，应该用上。

真源 `.md` 文件本身**分两层**，分工不同：

| 层 | 内容 | 适合谁 |
|---|---|---|
| **Schema 设计层** | 字段定义、必填项、扩展规则、命名约定、判定标准 | **plan owner**（设计决策） |
| **实例填充层** | 具体 component → file → line → anchor 的对应记录 | **executor**（grep / AST / Read 读代码事实） |

**正确的协作流**：

1. plan owner 写真源 .md 的 **schema 定义 + 1-2 个示范实例**（让 executor 理解格式即可）
2. executor 按 schema **扫全库填剩余实例**
3. plan owner 复审 executor 填的实例，纠正不合理或补遗漏

**违反检测（更新版）**：

- ❌ plan owner 写真源 .md 时把所有实例都自己手填——浪费 executor 能力，慢且易错
- ❌ executor 自己设计 schema / 决定哪些字段必填——它会跳过或简化（因为这是抽象设计任务）
- ✅ plan owner 写空的 schema + 1-2 示范实例 + 让 executor 按 schema 填剩余

**实证案例**：T1a fix v2 真源升级的修正后分工——
- plan owner 写 `axis-implementation-map.json` 的字段定义 + Button palette 的 1 条示范实例
- executor 扫全库填 DateTime / Steps / Tabs 等实例
- plan owner 复审填的内容

---

### 触发器 K：规则提案必须声明 enforcement 层级（L1-L5）

> **核心反模式**：plan owner 提议新规则时只写规则文本（L1 文档），没声明该规则的 enforcement 层级——结果"加了规则但仍然漏"。
> 后果：规则文档累积膨胀，AI 看了规则仍按 best effort 执行，遗漏问题反复出现；用户失去对规则有效性的信任。

**Enforcement 层级**（从弱到强）：

| 层级 | 机制 | 例子 | 可靠性 |
|---|---|---|---|
| **L1** 规则文档 | AI 读 + 自觉遵守 | R7 / R9 现状 | ⭐ 看 AI 是否记得 + 不偷懒 |
| **L2** 结构化输出 | prompt 模板强制输出字段（如"列已扫元素表"） | audit prompt 强制 evidenceLevel | ⭐⭐ 结构化降漏项 |
| **L3** 脚本辅助 | AI 必须调用脚本拿客观信号 | [`scripts/visual-diff.py`](../scripts/visual-diff.py)（R8 v2） | ⭐⭐⭐ 客观 measurement |
| **L4** Pre-commit hook | hook 强制运行，不通过不能 commit | INFRA-F21 hex literal hook | ⭐⭐⭐⭐ 强制执行 |
| **L5** CI gate | CI 跑测试，不通过不能 merge | INFRA-F20 视觉 baseline（v0.2 roadmap） | ⭐⭐⭐⭐⭐ 全员强制 |

**机械触发**：任何"提议新规则 / 升级规则 / 加 trigger"时，**强制**回答 3 个问题：

1. **这条规则的 enforcement 层级是几？**（L1-L5 选一个，标注在规则正文）
2. **为什么不能升级到 L3+？**（如果选 L1）
   - "工程成本明显高于价值" → 可接受 L1
   - "客观可测但没人写工具" → **不接受 L1**，必须同时写工具或标 "vN 待升 L3"
3. **L3+ 工具是什么？放哪？**（如 `scripts/X.py` / pre-commit hook / CI job）

**类别强制**：

| 规则类别 | 最低 enforcement 层级 |
|---|---|
| **视觉 / 客观可测的规则**（视觉对比、数值阈值、文件存在性） | **L3+** |
| **用户行为 / 协作 / commit format** | **L4+** |
| **跨人协作 / 防错代码 merge** | **L5** |
| **AI 自我约束 / 元规则**（如本规则） | L1 可接受（无法机械约束 AI 思考过程） |

**违反检测**：

- ❌ 起草新规则时没声明 enforcement 层级 → 红灯，回 step 1
- ❌ 选 L1 但没回答"为什么不能升 L3+"理由 → 红灯
- ❌ 视觉 / 客观可测规则选 L1 → 红灯，必须 L3+

**实证案例（2026-05-13 R7 测试 close-loop）**：

| 规则 | 初版层级 | 实测问题 | 升级路径 |
|---|---|---|---|
| **R8 v1**（视觉自检 5 步 protocol） | L1（主观对比） | AI"跑了 5 步"但漏 caret 实心 / back arrow 背景 — 主观对比不可靠；AI 主观估"≥95% match"实际客观工具测出 35% diff | **R8 v2 → L3**：强制调用 `scripts/visual-diff.py` 拿客观 diff%；threshold 不通过强制修 |

→ 这次发现让用户洞察："不停加规则、加描述还是会有遗漏"——根因是 L1 文档无法约束 AI 执行。修正：本 trigger K 把"提议时必须想 enforcement 层级"机械化，stop 凭"写下来就放心"的反模式。

---

### 触发器 L：AI 不确定时必须 ask + 列举疑问点（不自作主张）

> **核心反模式**：AI 遇到 ambiguous case 时默认"我来想办法 / 我来决定"，而不是 stop + 列举 + ask user。后果：(a) AI 自己拍的板用户可能不同意 → 用户 push back → 反复绕弯；(b) "用户没说所以我就做" 等于 AI 越权 — 用户不该当 reviewer 兜底 AI 的默认决策。

**机械触发**：任务执行中任何"不确定的 case"必须 stop + 列举疑问点 + ask user：

- 多种实现路径之间不知道选哪个
- 边界 case 不在已定规则覆盖范围内
- upstream signal 模糊（如 R10 case C/D — unnamed Group / 散乱 layers）
- 用户原 brief 没明说但需要决策的细节（如 hover state 颜色 / loading 时长 / 等）
- 视觉 / 设计决策（尺寸 / 间距 / 字体 weight / 颜色变体）
- 实现路径决策（哪个 library / 哪个 pattern / 单 SVG vs 多 SVG）
- 业务逻辑决策（error handling / loading state / edge case）

**正确措辞**：

- ✅ "下面 N 个 case 不确定，列出来等你拍板：
  1. case A: option X 还是 option Y？
  2. case B: ...
  3. ..."
- ❌ "我先按 X 做，你看效果不对再说" — 这是甩锅给用户当 reviewer

**违反检测**：

- ❌ 任何"我先按 X 做"（自作主张默认值）无 user 拍板
- ❌ AI 写完代码后才发现要 ask — 应该写之前 ask
- ❌ 提议"recommend 方案 A，OK 吗？" 不算 ask — 应该列出 A/B/C 让用户选（除非已被规则覆盖）
- ✅ AI 提出问题清单 + 推荐方案 + 等用户拍板

**例外**（可不 ask）：

- 用户明确说"你看着办" / "随便"
- 决策完全可逆（如临时 PoC）+ 用户已表态接受 iteration
- 已被 meta-rules / conventions 规则覆盖的 case（不重复 ask）

**实证案例（2026-05-13 R7 测试 close-loop）**：

- v6: AI 没 ask 选 approximate inline SVG vs Figma 真 vector，自作主张 approximate → 用户 push back "还是不对"
- v7: AI 没 ask 选 composite 4-layer 还是 single SVG export，自作主张 composite → 用户 push back "应该是一个完整的 svg 图"
- **纠偏**：开始 R7 logo 任务时应该先 ask: "logo 是 Figma Component（按单元导出）还是散乱 layers（各自处理）？你 Figma 那边看到的 node name 是什么？"

跟 R10 D case "AI 不能替设计师决定" 同根，提升为元规则覆盖所有 ambiguity。

---

### 触发器 M：排期决策必须读 tracker §排期原则（防"按耗时 / 复杂度 / 成本最低排"反模式）

> **核心反模式**：plan owner 提排期 / 推荐先做哪个 / 决定 v0.X 含哪些时，默认按"这项小先做 / 那项大推后 / 成本最低先做"——结果主线工作被推后、自动化前置被忽略、项目目标进度滞后。
> **后果**：(a) 项目目标关键能力 ship 节点反复后移；(b) AI / dev / 设计师协作链路缺口（如 mockup-side 全 L1）长期不补；(c) 用户反复纠正"为什么先做小的"。

**机械触发**：任何含以下信号词的回应**必须**先读 [`docs/internal/retrospection/design-spec-canonical-alignment-tracker.md`](internal/retrospection/design-spec-canonical-alignment-tracker.md) §排期原则段：

- "先做哪个 / 排个顺序 / 该 v0.X 还是 v0.Y / 这项放哪"
- "next sprint / next 2 周做什么 / 这周做什么"
- "v0.X 里包含哪些 / v1.0 触发条件 / 该不该升 minor"
- "并行 / 串行 / 先 A 还是先 B"

**排期权重（按优先级，照搬 tracker §排期原则）**：

1. **项目目标对齐** — 直接落地 [`PROJECT_GOAL.md`](./PROJECT_GOAL.md) 5 能力之一 → 最高
2. **依赖解锁** — 后续多项工作的前置 → 高（哪怕单项工作量大）
3. **自动化 / 标准化** — L1 文本规则升 L3+ → 高（呼应 trigger K）
4. **快速可交付独立项** — 0 阻塞 + 短 cycle → 顺路填空，**不挤主线**

**违反检测**：

- ❌ 任何"这项小，先做 / 这项 20-30h 太大推后 / 成本最低先做"措辞（除非已确认在主线依赖路径外）
- ❌ 排期表里把项目目标能力相关项排在"顺路"位置
- ❌ 没读 tracker §排期原则就提排期
- ✅ 排期表每项必须能答上"对齐 PROJECT_GOAL 哪个能力 / unblock 哪些后续项"
- ✅ 命名遵 0.x semver：破坏性走 0.x.0 minor，patch 只 non-breaking，1.0 = 稳定承诺

**实证案例（2026-05-13 session 9）**：

| 错的 | 正解 |
|---|---|
| 把 Phase 6.3/6.4/6.6/6.7/6.8 + BRIDGE-005 + EXTRACT-006 (~50-75h) 整块叫 "v1.0 major"、与 0.x 语义脱节 → 用户纠正"应该叫 0.2.x 或 0.3" | 按 0.x semver 重排：破坏性分散到 v0.3/v0.4/v0.5 minor，1.0 留给稳定承诺；同时按项目目标 5 能力把 Tier 1-A schema 化前置到 v0.3.0、Tier 1-B mockup audit 落进 v0.5.0（能力 4 第一个 L3+ gate） |
| Tier 1-A translation schema 化（"基础设施"）一开始没排进 release 主线，只列在"评估"段 | tracker §排期原则权重 1+2+3 三票通过 → 必须主线，落 v0.3.0 |

→ 这次发现让用户明确："以项目目标为首、不能按复杂度耗时排"。本 trigger M 把这条原则机械化。

### 触发器 N：默认并行 Agent 执行独立任务（防"承诺并行实际串行"反模式）

> 用户多次提醒"能并行就用并行 Agent"，AI 每次 acknowledge 但下次又默认 sequential = 承诺没进 muscle memory = trigger A 的现象，N 是机制化对策。

#### 触发条件（机械判断，命中即跳到 §应对）

任务包含 **≥ 2 个可独立完成的子任务**（输出物互不依赖、输入参数独立）。典型场景：

- 写 ≥ 2 个独立文件（不同目录 / 不同主题 / 互不引用）
- 跑 ≥ 2 个独立 audit / probe / search
- 对 ≥ 2 个独立 frame / page / section 做相同操作
- 编辑 ≥ 2 个互不依赖的文档段落

**不适用**（必须串行）：

- 后一步依赖前一步的产物（如先 grep 找 ID，再用 ID 改文件）
- 涉及同一文件的多处编辑（容易冲突）
- 需要用户中途决策的步骤之间

#### 应对（产物外化为强制 trace）

任务起手前必须输出**并行决策声明**（一句话或简表）：

```
Parallelism plan:
- Track 1 (independent): <task A>  → Agent / Tool call X
- Track 2 (independent): <task B>  → Agent / Tool call Y
- Track 3 (sequential, depends on Track 1): <task C>
```

然后**真的**在单一 message 中并发触发多个 Agent / Tool call（Claude Code 支持 "multiple tool uses in a single message"——参考 Agent tool description "When you launch multiple agents for independent work, send them in a single message with multiple tool uses so they run concurrently"）。

#### 反例（mandatory STOP 信号）

| ❌ AI 行为 | 触发的失败模式 |
|---|---|
| 任务有 2 个独立产物，AI 用 2 个 sequential message 各起 1 个 Agent | "默认串行" reflex 没被机制化对策拦下 |
| AI 写"我接下来跑 X，然后跑 Y"——本来 X / Y 互独立 | 没做 parallelism plan |
| 用户提醒"能并行吗" → AI 答"可以"但下一轮又串行 | 承诺没产物化（trigger A + N 双重命中）|
| AI 主动 acknowledge "下次会并行" 但没把规则落进 meta-rules | trigger B 联动失败 |

#### Acceptance

- 任何任务有 ≥2 个可独立子任务 → response 顶部必含 `Parallelism plan:` 段
- 该段必须列出每个 track 的输入 / 输出 / 是否 independent
- Independent tracks **必须**在单条 message 内并发触发，**不允许**串行 message
- 违例后用户提醒一次 → 立即写到本规则的实证段（如下方）作为新行

#### 与既有 trigger 关系

- 与 **trigger A** 联动（用户元提醒触发器）：N 是 A 的具体落地之一——把"能并行吗"这类元提醒变成机械化决策步骤
- 与 **trigger F** 联动（每次响应前最小自检）：F 是 checklist，N 是 checklist 中的一项"是否 ≥2 独立子任务？是 → parallelism plan"
- 与 **M35** 联动（mockup-conventions affordance trace）：两者同源——把隐性思考外化为可 audit 的产物

#### 实证

- **2026-05-18** Touch-Screen v8 session：用户提醒"为什么默认单 Agent，不能并行"——AI acknowledge 并临时切换并行（2 个 audit script agents 并发），但**之前 4 个独立任务**（M27/M28/M34 stub 化 + R1 stub + 2 SKILL refresh + meta-rules 更新）都是 sequential 单 message 跑的。用户元提醒触发本 trigger 立规则。**根因**：AI 默认 reflex 是"一个一个 tool call 跑"，没有把 parallelism 作为起手必做的产物化步骤。

---

## 7. 元说明

- 本文件是元规则真源——具体规则（如 prop-aliases、divergences、topology-mapping）是本元规则的**实例落地**
- 修改本文件需谨慎——所有项目规则的最高约束都在这
- 任何 AI 工具的入口（CLAUDE.md / 未来的 GEMINI.md / CURSOR.md 等）应仅登记**该工具自己特有的工程细节**，元规则与角色行为约束统一指向本文件

---

## 附录：本规则的实证沉淀（避免重犯）

| 实例 | 违反的反模式 / 触发器 | 正解 |
|---|---|---|
| 推荐"硬编码 darkTheme 全局别名 + TODO" | #1 (硬编码项目级规则) | 先登记到 prop-aliases.md，工具读它 |
| audit prompt 列 8 类 verdict 没加溯源字段 | #3 (to-do list 思维) | 先设计 evidenceLevel schema |
| 把 DateTime 作为特例处理 | #2 (打补丁不抽象) | 抽象成 topology-mapping 机制 |
| audit 只查 CSS class 没考虑 prop / palette | #5 (没问扩展时改哪里) | 4 层级查找框架（CSS class / prop / palette / 拓扑映射） |
| 单日产出 5 个结构性升级，没主动写复盘 | 触发器 D (阶段完成判定模糊) | 满足任一硬条件（≥ 3 个真源 .md 改 / ≥ 5 阶段 / 完成 v2 子任务）→ 必须写复盘 |
| 用户连续 5 次主动提醒"该做但漏做的事" | 触发器 A (没识别元提醒信号) | 信号词列表机械检测；信号出现 → 停下当前任务，先回应元层面 |
| 写"M1 后再加规则"用"避免越界"做防御借口 | 触发器 E (用户决策疲劳后还推方案) | 真越界=反复改同一文件；加新真源文件=机制化落地，不算越界 |
| Round 1 plan-only prompt 让 executor 设计 axis-implementation-map.json schema + 写实例草稿 | 触发器 G (踢任务) + 反模式 #3 (to-do list 思维) | 真源文件 plan owner 自己写完作为 prompt 输入；executor 只做"按已定 schema 扩展执行" |
| 多次推荐"今天到这里停"作为对话节点，把 AI 包进"我们都累了" | 触发器 H (投射人类疲劳) | AI 不累；判断标准是 context window + 任务输入清晰度 + 用户精力，不是时间 |
| Round 3 prompt 把 grep/awk 命令缺陷误判为数据 bug，让 executor 修 Tooltip / Select 不存在的"消失" | 触发器 I (没做 JSON 真源核查) | 用 `node -e "JSON.parse(...)"` 核查 JSON 真源；命令缺陷不等于数据 bug |
| 用户说"记住 Figma plan = Pro" → 直接 Save 到 Claude Code 工具级 memory，没问"其它 AI 工具是否也需要这条约束" → Codex / Gemini / Cursor 等其它工具看不到 → 用户主动指出 | 反模式 #1 (硬编码项目级规则到工具级机制) + 触发器 B 子规则缺失 | 保存事实前机械跑"作用域"判断：跨工具约束 → 真源 .md（AGENTS.md "项目约束" 段）；工具人格 → memory。详见触发器 B 子规则"保存事实前问作用域" |
| 状态汇总把"plan 决策落地"和"代码执行落地"挤进同一表格 cell（如 "T3 先 → T2 样板换 Badge/Tooltip/Select \| ✅ 完成 \| commit 0fb0d29"），让用户误以为 T3 已执行——实际只改了 v2 plan 文字 | 反模式 #3 (to-do list 思维 / 没产出契约) | 状态汇总**强制分两 section**：(1) Plan-level（文档/决策落地，commit X）；(2) Execution-level（代码/脚本/工件落地，commit Y / diff Z 行）。两层不能混。每条状态必须用动词区分——"修了 plan / 改了文档" vs "执行了 / 跑了 / 改了代码" |
| MicroApps Console mockup session 中 AI 被问"是否加 M21 库消费规则" → 直接 propose 4 条新规则，没先 grep `mockup-conventions.md` —— 实际 M1（库 key 过滤 + 同名旧库陷阱警告）+ M10（不写 hex literal）+ 真源/优先级段已 100% 覆盖 | 触发器 J (加规则前没查重) | 任何新规则提议前必须 grep 至少 3 个关键词、列出查的文件 + 命中情况，证据放在回复里。无命中才能起草。 |
| MicroApps Console Health Indicator 选了 TVU UX Design System `icon/Message/warning 2`（fill 风格），与 Success 1 + Error 3 的 line 风格不一致 —— 凭"颜色对"选 variant，没核对图标轮廓 | 反模式 #2 (打补丁不抽象) + M2 acceptance criteria (convenience over discipline) | 选库 component variant 时必须**渲染对比**——一次 import 全部候选放一行 32px 实例截图，看清 line vs fill / 几何形状一致性后再确定。颜色绑色变量是必要条件不是充分条件。 |
| 把 Phase 6.3/6.4/6.6/6.7/6.8 + BRIDGE-005 + EXTRACT-006（~50-75h）整块叫 "v1.0 major"，与 0.x semver 脱节；Tier 1-A schema 化只列"评估"段，没排进 release 主线 | 触发器 M (排期决策反模式 — "按 1.0 大变更" 思维 + "基础设施不算主线" 思维) | 0.x semver：破坏性走 0.x.0 minor，1.0 = 稳定承诺；Tier 1-A 因为对齐能力 5 + unblock 多项 → 必须主线（v0.3.0）；按 tracker §排期原则的权重 1+2+3 排，不按耗时大小 |
