# 0.6.8 计划：推荐 → 调整 → 冻结设计包

> 状态：**已实现（0.6.8）** · 目标版本：`0.6.8` · 前置：`0.6.7`（principle 卡）
> 范围：卡片元数据、preview 视觉参考、`recommend`、`capture-pack`。

## 1. 为什么要这四件

0.6.7 之前，设计库能按 appType/platform/style 检索，但没法回答：

- 这是“会员中心”还是“数据看板”的参考？
- 气质是 calm / energetic / luxury？
- 密度是低/中/高？
- 有没有可打开的 HTML 视觉参考？
- 用户从 3 套候选里选了哪套、最后冻结成什么？

0.6.8 把推荐变成闭环：**metadata → recommend → 用户调整 → capture-pack 冻结 → 下一轮优先推荐**。

## 2. 卡片元数据

`DesignCard` 新增可选字段：

```jsonc
{
  "moduleTags": ["member-center", "dashboard", "onboarding", "empty-state"],
  "tone": ["calm", "energetic", "luxury"],
  "density": "low | medium | high",
  "colorProfile": { "temperature": "warm | cool | neutral", "contrast": "low | medium | high" },
  "preview": "design-packs/sculptural-member-center-v1/preview/index.html"
}
```

- `moduleTags`、`tone`：最多 12 个，小写短标签（ingest 时 lowercase + trim）；
- `density`：只接受 low/medium/high，非法值警告并忽略；
- `colorProfile`：**不手填**，从 `tokens.palette` 推导：
  - temperature：调色板平均 (R−B) > 12 → warm，< −12 → cool，否则 neutral；
  - contrast：调色板最亮/最暗相对亮度比 ≥ 7 → high，≥ 3 → medium，否则 low；
  - 无 palette → 不写。
- `preview`：相对 `.shared` 的 HTML 路径，只允许 `.html`、不允许绝对路径或 `..`；只是视觉参考，**不是生产代码**。
- 所有字段进入检索：module/tone/density 参与过滤与推荐加分；preview 不进 BM25，只渲染到 brief/选项。

## 3. recommend

`dwguard_design recommend` 输入：需求、module、appType、platform、品牌色、tone/density（可选）、`topK`（默认 3）。
输出：

- `tasks/design-options.md`：3 套候选（方向、锚点卡片、tokens、为什么、代价、preview、建议的 principle/AP）；
- `.shared/design-library/recommendations.json`：机器可读的 options，供 capture-pack 使用。

推荐逻辑（可解释、非“凭感觉”）：

1. 硬过滤：active、pattern、license 可用；
2. 检索：BM25/hybrid 取 30 个候选；
3. 加分：module 命中 +0.40、appType 命中 +0.20、platform 命中 +0.12、tone 命中 +0.18、density 命中 +0.12、品牌色温度匹配 +0.08；
4. 多样性：按 stylePriority/tone 去重，最多 3 套；
5. 每套选 1–2 张 principle（方向）与锚点卡上的 AP（禁止项），给出代价（misuses/AP/深色模式/性能重验）。

> 推荐不承诺“唯一最合适”；给 3 套并说明代价，由用户拍板。

## 4. capture-pack

`dwguard_design capture-pack` 输入：`choice`（opt-1…）、`name`、可选 `preview`。

必须同时满足：`confirmed: true` + 当前 specVersion 的**四维审计通过** + 对应的 `dwguard_confirm` 记录。缺一拒绝，避免把中间稿当范式。
输出 `.shared/design-packs/<name>/`：

```text
├─ README.md                 # 需求、选择、适用维度、为什么、代价、审计/确认
├─ cards/*.meta.json         # inbox 兼容的可移植卡片（不带内部 id/status）
├─ pack.json                 # 角色、审计/确认哈希、适用维度、preview、完整卡片
└─ preview/index.html        # 可选，仅视觉参考
```

同时向设计库追加一张 **范式卡**（kind pattern）：

- 标题：`范式包 · <name>`；
- tokens 取自锚点卡；
- `moduleTags/tone/density/colorProfile/preview` 带上；
- `source.kind: project`，`ref: design-pack:<name>`；
- `packRef: <name>` + `componentIds`，标记这是被接受过的组合；
- `weight: 1.2`，作为后续 recommend 的优先候选。

## 5. 生命周期

```text
需求/模块/品牌色
  → recommend（3 套）
  → 用户选/改
  → design-brief + spec
  → DevEco 实现（preview 只对照，不抄代码）
  → 四维审计通过
  → dwguard_confirm
  → capture-pack 冻结 v1（cards meta + pack 证据）
  → feedback useful
  → 下一次 recommend 优先命中范式包
```

中间稿不冻结；只有“审计通过 + 用户确认”的版本才生成 pack 和范式卡，避免过拟合。

## 6. 验收标准（可证伪）

| ID | 判据 | 验证 |
| --- | --- | --- |
| MD-1 | ingest 成功写入 moduleTags/tone/density/preview；非法 density/preview 字段被忽略并警告（卡片仍可入库） | 单测：manifest |
| MD-2 | colorProfile 从 palette 自动推导，无 palette 不写 | 单测：深/浅/暖/冷调色板 |
| MD-3 | search 的 module/tone/density 过滤生效 | 单测 |
| RC-1 | recommend 输出 3 套候选，含 tokens/why/cost/preview，写入 options md + recommendations.json | 单测 |
| RC-2 | 候选按多样性去重，module/appType 命中优先 | 单测：构造不同卡片 |
| CP-1 | capture-pack 缺 confirmed / 四维审计 / 用户确认时拒绝；齐全后生成 README/cards/pack.json/preview | 单测 |
| CP-2 | 包内 `cards/*.meta.json` 是 inbox 兼容格式，可直接投回空库 re-ingest，kind/tokens/元数据不丢 | 单测：空 workspace + 卡包 ingest |
| CP-3 | `pack.json` 带 status/角色/审计与确认哈希/preview；范式卡带 packRef/componentIds，下一轮检索可命中 | 单测 |
| CP-4 | pack.json 与 pack import 兼容 | 单测/字段检查 |

## 7. 不做什么

- 不做自动“审美评分”或“唯一最佳推荐”；
- 不复制/执行 preview HTML，不把它当验收证据；
- 不每次调整都学习，只冻结“四维审计通过 + 用户确认”的版本；
- 不引入向量库/模型；recommend 仍用确定性检索 + 可解释加权。
