cardbuddy 0.13.3 → 0.14.1
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.
- package/README.md +7 -3
- package/dist/cli.js +4 -4
- package/dist/config.js +7 -7
- package/dist/init.js +15 -4
- package/dist/portGuard.js +2 -2
- package/dist/preview-editor/assets/index-DnXqKrCc.js +307 -0
- package/dist/preview-editor/assets/index-cbTCHp8J.css +1 -0
- package/dist/preview-editor/index.html +2 -2
- package/dist/standalone.js +14 -6
- package/dist/vendored/card-editor/api.js +6 -6
- package/dist/vendored/mcp/client.mjs +53 -3
- package/dist/vendored/mcp/tools.mjs +17 -1
- package/dist/vendored/server/core/ai-chat.js +1443 -271
- package/dist/vendored/server/core/cardFiles.js +271 -39
- package/dist/vendored/server/core/cardImportMeta.js +16 -0
- package/dist/vendored/server/core/chatHistory.js +122 -0
- package/dist/vendored/server/core/index.js +10 -3
- package/dist/vendored/server/core/turnJournal.js +386 -0
- package/dist/vendored/skills/card-skill-trainer/SKILL.md +399 -222
- package/dist/vendored/skills/card-skill-trainer/scripts/build_dataset.py +103 -19
- package/dist/vendored/skills/card-skill-trainer/scripts/diagnose_case.mjs +378 -200
- package/dist/vendored/skills/card-skill-trainer/scripts/lib/runs.mjs +147 -0
- package/dist/vendored/skills/card-skill-trainer/scripts/lib/scoring.mjs +297 -4
- package/dist/vendored/skills/card-skill-trainer/scripts/plan_next_round.mjs +484 -0
- package/dist/vendored/skills/card-skill-trainer/scripts/round_diff.mjs +77 -96
- package/dist/vendored/skills/card-skill-trainer/scripts/run_round.mjs +237 -62
- package/dist/vendored/skills/card-skill-trainer/scripts/score_round.mjs +74 -35
- package/dist/vendored/skills/dsl-card-ai/SKILL.md +15 -2
- package/dist/vendored/skills/dsl-card-generator/SKILL.md +5 -3
- package/dist/vendored/skills/dsl-card-generator/references/generation_pitfalls.md +120 -0
- package/dist/vendored/skills/dsl-card-generator/references/previewer_contract.md +10 -0
- package/dist/vendored/skills/dsl-card-generator/references/quickref.md +15 -1
- package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/canvas-radar.json +2 -2
- package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/scatter-pill-band.json +10 -0
- package/dist/vendored/skills/dsl-card-generator/references/recipes.md +43 -1
- package/dist/vendored/skills/dsl-card-generator/references/rules.md +33 -6
- package/dist/vendored/skills/dsl-card-generator/references/slices_convention.md +12 -5
- package/dist/vendored/skills/dsl-card-generator/scripts/add_component.mjs +5 -10
- package/dist/vendored/skills/dsl-card-generator/scripts/crop_slices.mjs +47 -10
- package/dist/vendored/skills/dsl-card-generator/scripts/expand_ir.mjs +12 -4
- package/dist/vendored/skills/dsl-card-generator/scripts/lib/design_sample.mjs +388 -328
- package/dist/vendored/skills/dsl-card-generator/scripts/lib/slice_pixels.mjs +109 -0
- package/dist/vendored/skills/dsl-card-generator/scripts/render_card.mjs +45 -7
- package/dist/vendored/skills/dsl-card-generator/scripts/route_input.mjs +7 -3
- package/dist/vendored/skills/dsl-card-generator/scripts/spec_audit.mjs +110 -23
- package/dist/vendored/skills/dsl-card-generator/scripts/spec_to_schema_v3.mjs +2954 -127
- package/dist/vendored/skills/dsl-card-generator/scripts/spec_tree.mjs +128 -3
- package/dist/vendored/skills/dsl-card-generator/scripts/validate_schema.py +28 -0
- package/dist/vendored/skills/finmall-card-sync/SKILL.md +1 -1
- package/dist/vendored/skills/finmall-session-navigator/SKILL.md +1 -1
- package/dist/vendored/skills/finmall-session-navigator/scripts/session-manager.mjs +1 -1
- package/dist/vendored/skills/shared/finmall-config.mjs +4 -4
- package/dist/vendored/skills/sketch-spec-to-card/SKILL.md +2 -2
- package/dist/vendored/skills/sketch-spec-to-card/scripts/parse_meaxure.py +29 -2
- package/dist/vendored/tools/finmall-env.mjs +6 -6
- package/package.json +1 -1
- package/dist/preview-editor/assets/index-CQScMhyg.css +0 -1
- package/dist/preview-editor/assets/index-pW1J4vP3.js +0 -276
- package/dist/vendored/skills/card-skill-trainer/baselines/v3-r038n.json +0 -43
- package/dist/vendored/skills/card-skill-trainer/baselines/v3-r039n.json +0 -47
- package/dist/vendored/skills/card-skill-trainer/baselines/v3-r050n.json +0 -48
|
@@ -1,138 +1,185 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: card-skill-trainer
|
|
3
|
-
description: 无人值守联合训练 sketch-spec-to-card 与 dsl-card-generator。扫描桌面已确认 Sketch 导出,评估卡片聚焦与标注契约,批量生成 schema/data,渲染截图,执行结构、事实与像素评分,输出失败归因和下一轮规则候选。触发词:卡片训练、自动训练、训练闭环、skill 回归、还原度优化。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Card Skill Trainer
|
|
7
|
-
|
|
8
|
-
## 定位
|
|
9
|
-
|
|
10
|
-
本 Skill 联合训练 `sketch-spec-to-card` 和 `dsl-card-generator`:前者负责卡片聚焦与标注契约,后者负责 DSL 还原,两者都被当作被评测对象。
|
|
11
|
-
|
|
1
|
+
---
|
|
2
|
+
name: card-skill-trainer
|
|
3
|
+
description: 无人值守联合训练 sketch-spec-to-card 与 dsl-card-generator。扫描桌面已确认 Sketch 导出,评估卡片聚焦与标注契约,批量生成 schema/data,渲染截图,执行结构、事实与像素评分,输出失败归因和下一轮规则候选。触发词:卡片训练、自动训练、训练闭环、skill 回归、还原度优化。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Card Skill Trainer
|
|
7
|
+
|
|
8
|
+
## 定位
|
|
9
|
+
|
|
10
|
+
本 Skill 联合训练 `sketch-spec-to-card` 和 `dsl-card-generator`:前者负责卡片聚焦与标注契约,后者负责 DSL 还原,两者都被当作被评测对象。
|
|
11
|
+
|
|
12
12
|
```text
|
|
13
|
-
build_dataset.py →
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
## 源码隔离铁律
|
|
19
|
-
|
|
20
|
-
训练、评测和冒烟测试**绝不写入宿主源码目录**:
|
|
21
|
-
|
|
22
|
-
- 禁止写 `src/cards/`
|
|
23
|
-
- 禁止写 `src/slices/`
|
|
24
|
-
- 禁止写 `.card-baselines/`
|
|
25
|
-
- 原始桌面设计稿只读
|
|
26
|
-
- 所有生成物落在 `training/datasets/<version>/raw/` 或 `training/runs/<round>/`
|
|
27
|
-
|
|
28
|
-
执行器必须在动态 import 生成器和渲染器之前设置:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
DSL_CARD_CARDS_DIR=<training-run>/cards
|
|
32
|
-
DSL_CARD_SLICES_DIR=<training-run>/slices
|
|
13
|
+
build_dataset.py → build_sample.mjs(结构去重抽样)
|
|
14
|
+
→ run_round.mjs(收尾自动调 score_round:summary.json/md + roundGate)
|
|
15
|
+
→ plan_next_round.mjs(归因聚类 / 焦点集 / 晋级门 / 盲测门 / 收敛信号)
|
|
16
|
+
→ diagnose_case.mjs(逐例证据包,支持批量)
|
|
17
|
+
→ 修生成器或解析器 → semantic-review.jsonl / lessons.jsonl
|
|
33
18
|
```
|
|
34
19
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
20
|
+
人工不阻塞主流程。连续回归、渲染器崩溃或置信度低于阈值的样本会进入 `review-queue.jsonl`(带 `failureClass` 与未达标维度,可直接聚类);像素/结构失败同时生成 `semantic-review.jsonl`,由执行 Skill 的 Agent 在下一轮自动做多模态归因,再回灌到 `dsl-card-generator` 或 `sketch-spec-to-card` 的文档规则。脚本负责提出证据和复跑回归,不负责把业务语义硬编码。
|
|
21
|
+
|
|
22
|
+
**口径唯一来源**:单案例门(`PASS_GATE`)、轮级门(`ROUND_GATE_TARGETS`)、盲测门(`GENERALIZATION_GATE`)、失败签名与失败类归因全部定义在 `scripts/lib/scoring.mjs`;轮次/锚点读取与轮间对比定义在 `scripts/lib/runs.mjs`。run_round / score_round / round_diff / plan_next_round / diagnose_case 一律 import 复用,**禁止在脚本里另写一套阈值**——`tools/tests/scoring.test.mjs` 会反向断言本文档验收表里的数字与 `PASS_GATE` 逐条一致,改门必须同步改文档。
|
|
23
|
+
|
|
24
|
+
## 源码隔离铁律
|
|
25
|
+
|
|
26
|
+
训练、评测和冒烟测试**绝不写入宿主源码目录**:
|
|
27
|
+
|
|
28
|
+
- 禁止写 `src/cards/`
|
|
29
|
+
- 禁止写 `src/slices/`
|
|
30
|
+
- 禁止写 `.card-baselines/`
|
|
31
|
+
- 原始桌面设计稿只读
|
|
32
|
+
- 所有生成物落在 `training/datasets/<version>/raw/` 或 `training/runs/<round>/`
|
|
33
|
+
|
|
34
|
+
执行器必须在动态 import 生成器和渲染器之前设置:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
DSL_CARD_CARDS_DIR=<training-run>/cards
|
|
38
|
+
DSL_CARD_SLICES_DIR=<training-run>/slices
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
每轮结束后可用 `git status --short -- src` 验证必须为空。
|
|
42
|
+
|
|
43
|
+
## 自动化流程
|
|
44
|
+
|
|
45
|
+
1. 扫描所有包含 `index.html` 的 MeaXure 导出。
|
|
46
|
+
2. 每套导出独立解析到 `training/datasets/<version>/raw/<source>/`,不修改桌面源文件。
|
|
47
|
+
3. 将每个有效画板登记为一个案例,按内容哈希稳定划分 train/dev/eval/holdout。
|
|
48
|
+
4. 使用 `v3` 策略批量生成到隔离的 run 目录(本技能是「多画板必须先选卡」铁律的**显式批量例外**:用户点名跑无人值守训练即等于授权全量画板;产物落隔离 run 目录、不写 `src/cards/`。见 `dsl-card-generator/references/rules.md §十三`)。
|
|
49
|
+
5. 复制 schema 实际引用的 slices 到当前 run 的隔离资源目录。
|
|
50
|
+
6. 执行 Python 结构校验、Node lint、独立 Chrome 渲染、重复内容检测和像素差异计算。
|
|
51
|
+
7. 聚合 Round 报告(`run_round.mjs` 收尾自动调用 `score_round.mjs`),按主失败签名与失败类出直方图。
|
|
52
|
+
8. `plan_next_round.mjs` 把「归因 → 聚类 → 焦点集 → 门禁判定 → 收敛信号 → lesson 草稿」一次算完,产出 `next-round-plan.json` 与 `lesson-drafts.jsonl`(`status=candidate`,人工审批后才落盘 lessons)。Agent 按聚类逐例复核 `designImage + render.png + spec.json`,把失败归入 PARSER / DSL / STYLE / DATA / INTERACTION / ASSET / EVALUATOR,并只推广通用规则。
|
|
53
|
+
|
|
54
|
+
## 高效迭代闭环(r172 起;r263 补自动归因与增量轮补齐)
|
|
49
55
|
|
|
50
56
|
单案例修复循环按此顺序推进,避免整轮盲跑浪费时间:
|
|
51
57
|
|
|
52
|
-
1.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
58
|
+
1. **计划**:`plan_next_round.mjs --run training/runs/<上轮> --anchor training/anchors/r176.json`
|
|
59
|
+
一次给出失败聚类(含建议修复落点)、焦点集 `--only` 清单、锚点晋级门判定、跨轮重复签名与
|
|
60
|
+
收敛信号、可直接粘贴的下一轮命令。先看聚类再动手,别逐例盲翻报告。
|
|
61
|
+
2. **诊断**:`diagnose_case.mjs --run <上轮> --case <id1,id2,...> --out <json>` 批量产证据包
|
|
62
|
+
(多案例共用一套渲染会话):门禁未达标维度(按缺口降序)、失败类归因、掩膜覆盖率、上游聚焦门、
|
|
63
|
+
side-by-side、像素热区、元素偏差表、`__prov` 源码行溯源、失败类建议。先看偏差表与热区,
|
|
64
|
+
再决定是否动生成器。
|
|
65
|
+
3. **修复**:改动 `spec_to_schema_v3.mjs` / `vision.py` / `parse_meaxure.py` 的通用几何规则
|
|
66
|
+
(禁业务词硬编码)。
|
|
67
|
+
4. **增量验证**:`run_round.mjs --round <新轮> --focus training/runs/<上轮> --inherit training/runs/<上轮>`
|
|
68
|
+
只重跑焦点集(失败例 + 低分通过例),其余案例报告与截图从上一轮继承 → 新轮仍是**完整可比轮**
|
|
69
|
+
(passRate 分母正确、`round_diff` 不会把未重跑案例算成 removed)。只重跑失败例用
|
|
70
|
+
`--only-failed`;进程被 kill / 渲染假死后续跑用 `--resume`(已有报告的案例跳过)。
|
|
71
|
+
5. **整轮防回归**:不带选样开关跑全量,`round_diff.mjs --from <锚点> --to <新轮>` 确认零
|
|
72
|
+
PASS→FAIL 回归(该脚本存在回归时 exit 1,可直接当提交门禁;`--json` 出机器可读结论)。
|
|
73
|
+
6. **门禁汇总**:run_round 收尾已自动出 roundGate(`--no-summary` 可关);晋级前再跑
|
|
74
|
+
`plan_next_round.mjs --run <新轮> --anchor <锚点> [--blind <盲测轮>]` 取机器判定。全绿才提交推送。
|
|
75
|
+
|
|
76
|
+
> **继承轮不是锚点**:`--inherit` 轮的 `cards/`、`slices/` 只含本轮重跑案例,因此可用于门禁与
|
|
77
|
+
> 回归对账,但**不能作为冻结锚点载体**——锚点必须整轮全量跑(含全部 cards/slices 证据)。
|
|
78
|
+
|
|
79
|
+
### 校正器纪律
|
|
80
|
+
|
|
81
|
+
后置布局校正器是安全网而不是拐杖:
|
|
82
|
+
|
|
83
|
+
- 校正采纳需**双指标守卫**:position 提升 **且** pixel 不退化(容忍 +0.005),否则回退并记
|
|
84
|
+
`correctorRejected`;采纳时记 `layoutCorrections` 明细。
|
|
85
|
+
- `summary.json` 的 `correctorCoverage`(触发率)持续 >25% 说明生成器缺陷被校正器掩盖,
|
|
86
|
+
应把高频校正模式沉淀回生成器规则,而不是放任校正器兜底。
|
|
87
|
+
- 每 3~5 轮安排一次里程碑裸测:`run_round.mjs --no-correct --round <轮次>nc`,与同期
|
|
88
|
+
正常轮对比 passRate/avgPosition,差值就是校正器的真实贡献与生成器的真实缺口。
|
|
89
|
+
- 模拟否决快路径:纯纵向 rigidSafe 校正的 position 分可精确模拟(22/22 对账逐位一致),
|
|
90
|
+
模拟不提升即跳过二次渲染,报告记 `correctorRejected.reason=position-not-better-simulated`;
|
|
91
|
+
可用 `CORR_SIM_VALIDATE=1` 双跑对账复核保真度。
|
|
92
|
+
|
|
93
|
+
### 分区纪律
|
|
94
|
+
|
|
95
|
+
- 迭代修复**只用 train/dev**;eval 每 3 轮盲测一次;holdout 只在晋级落地时启用。
|
|
96
|
+
- 同一案例连续出现在诊断视野里超过 2 轮,视为过拟合风险,下一轮诊断必须换一批样本。
|
|
97
|
+
|
|
98
|
+
## 上游质量门
|
|
99
|
+
|
|
100
|
+
每个案例先检查 `sketch-spec-to-card` 产物,再进入 DSL 评分:
|
|
101
|
+
|
|
102
|
+
- `annotationCompleteness`:画板内叶子标注是否被完整归属到聚焦卡。
|
|
103
|
+
- `textRetention`:卡片内文案是否被完整保留。
|
|
104
|
+
- `structuralFocus`:候选是否具备卡片级结构,而不是气泡、按钮条或空壳。
|
|
105
|
+
- `trainingEligible`:弹窗、toast、底部抽屉必须为 false。
|
|
106
|
+
|
|
107
|
+
任一门失败优先归因 `PARSER`,修复目标是 `vision.py` / `parse_meaxure.py` / `boundary.json` 的通用几何规则,不允许用业务名救某个样本。
|
|
108
|
+
|
|
109
|
+
## 验收标准(r060 起)
|
|
110
|
+
|
|
111
|
+
### 单案例通过门(per-case pass gate)
|
|
112
|
+
|
|
113
|
+
每张卡片必须同时满足以下全部条件才算 PASS:
|
|
114
|
+
|
|
115
|
+
| 维度 | 门(`lib/scoring.mjs::PASS_GATE`) | 说明 |
|
|
98
116
|
|---|---:|---|
|
|
99
|
-
| 像素差异 (pixelDiff) | **≤ 0.08** |
|
|
100
|
-
| UI 还原度 (overall) | **≥ 0.85** | 综合像素+结构+组件+文本 |
|
|
101
|
-
| 组件相似度 (components) | **≥ 0.75** | 文本/媒体/富文本计数匹配(ListLayout 按数据项展开计数) |
|
|
102
|
-
| 位置还原度 (position) | **≥ 0.80** | 文本盒对齐(含形状锚点) |
|
|
103
|
-
| 文本溢出 (textOverflow) | **≥ 0.90** | 渲染盒溢出/裁切 |
|
|
104
|
-
| 结构还原度 (structure) | **≥ 0.85** | 轮廓直方图(含 1.25% 容差窗) |
|
|
105
|
-
| 色彩还原度 (color) | **≥ 0.90** | 颜色分布相似度 |
|
|
106
|
-
| 尺寸还原度 (dimension) | **≥ 0.95** | 宽高比匹配 |
|
|
107
|
-
| 重复内容 (duplication) | **≥ 0.95** | 同一文案渲染次数不得超出标注次数 5%;合并渲染(¥+金额 合一)豁免 |
|
|
117
|
+
| 像素差异 (pixelDiff) | **≤ 0.08** | 逐像素差异比;标注缺陷矩形、非标字体字形带、以及「导出素材缺失→画板裁切兜底切图」(reason=crop-fallback-slice,仅掩 schema 真实引用的裁切盒)局部掩膜(报告 pixelExclusions 透明可见) |
|
|
118
|
+
| UI 还原度 (overall) | **≥ 0.85** | 综合像素+结构+组件+文本 |
|
|
119
|
+
| 组件相似度 (components) | **≥ 0.75** | 文本/媒体/富文本计数匹配(ListLayout 按数据项展开计数) |
|
|
120
|
+
| 位置还原度 (position) | **≥ 0.80** | 文本盒对齐(含形状锚点) |
|
|
121
|
+
| 文本溢出 (textOverflow) | **≥ 0.90** | 渲染盒溢出/裁切 |
|
|
122
|
+
| 结构还原度 (structure) | **≥ 0.85** | 轮廓直方图(含 1.25% 容差窗) |
|
|
123
|
+
| 色彩还原度 (color) | **≥ 0.90** | 颜色分布相似度 |
|
|
124
|
+
| 尺寸还原度 (dimension) | **≥ 0.95** | 宽高比匹配 |
|
|
125
|
+
| 重复内容 (duplication) | **≥ 0.95** | 同一文案渲染次数不得超出标注次数 5%;合并渲染(¥+金额 合一)豁免 |
|
|
108
126
|
| validate / lint / render | 0 | 零容忍 |
|
|
109
127
|
|
|
128
|
+
> **未达标维度按缺口排序落盘**:报告里的 `gateFailures`(全部未过门维度 + 归一化缺口)、
|
|
129
|
+
> `failureSignature`(缺口最大维度对应签名)、`failureClass` / `failureReason`(归因)由
|
|
130
|
+
> `evaluatePassGate` / `attributeFailure` 统一产出,review-queue 与 summary 直方图同源。
|
|
131
|
+
> 签名口径 v2(r263 起)取「归一化缺口最大」的维度,不再按写死优先级命中即返回——旧口径会把
|
|
132
|
+
> `comp=0.42 / pos=0.42` 的缺组件卡报成 `duplicate-content-detected`(重影只超 1 处),把下一轮带偏。
|
|
133
|
+
> 跨轮签名趋势对比以口径 v2 之后的轮次为界。
|
|
134
|
+
|
|
110
135
|
> **字体掩膜口径(r201 起)**:非标字体字形带的掩膜扩宽比不再硬编码,取自 `training/reports/font-metrics.json`
|
|
111
136
|
> ——由 `training/tools/probe_font_metrics.mjs`(playwright `measureText` 实测设计稿字体栈的渲染宽 / 标注宽比)产出。
|
|
112
137
|
> 取值顺序:逐样本比例 → 同 fontSize 档中位数 → overall 中位数 → 文件缺失回退 `1.35`。
|
|
113
138
|
> 换字体栈、改 `card-editor/styles/app.css` 或改掩膜逻辑后**必须重跑探针**(`node training/tools/probe_font_metrics.mjs`),
|
|
114
139
|
> 否则 pixelDiff 口径漂移、轮间与锚点不可比。
|
|
140
|
+
> **掩膜门环境感知(seq4 起)**:掩膜门不再只看字体家族名——探针实测「回退栈宽/标注宽」
|
|
141
|
+
> `fontMaskWiden > 1.06` 即该字体在本机渲染环境不可得(PingFang SC 在 Windows 同样回退合成),
|
|
142
|
+
> 一律掩膜;探针缺失回退家族名判据。否则设计稿字体与训练环境字体差会把像素门顶在
|
|
143
|
+
> 8% 门外(实测卡 4 文本字形带单带 16-36%),误逼生成器改字重/字号扭曲 spec。
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
> **掩膜覆盖率护栏(r263 起)**:掩膜是「不计分」而不是「还原对」。报告新增
|
|
148
|
+
> `exclusionCoverage{total,byReason}`,summary 出 `avgExclusionCoverage` 与 `highMaskCases`;
|
|
149
|
+
> 单案例掩膜面积 ≥ `MASK_REVIEW_THRESHOLD`(25%)时,`score_round` 与 `plan_next_round` 都会点名
|
|
150
|
+
> (信号 `pass-by-mask`),该案例的 PASS **不得计入晋级证据**,必须先看图复核。
|
|
115
151
|
|
|
116
152
|
### 轮级晋级门(round-level promotion gate)
|
|
117
153
|
|
|
118
|
-
一轮训练完成后,用 `round_diff.mjs --from
|
|
119
|
-
**回归 0 例 PASS→FAIL
|
|
120
|
-
|
|
154
|
+
一轮训练完成后,用 `round_diff.mjs --from <冻结锚点> --to <本轮>` 做冻结锚点回归,
|
|
155
|
+
**回归 0 例 PASS→FAIL 且均值不退化**才允许晋级;机器判定用
|
|
156
|
+
`plan_next_round.mjs --run <本轮> --anchor <冻结锚点>`(同一份对比逻辑,出 `promotionGate.passed`)。
|
|
157
|
+
|
|
158
|
+
锚点有两种载体,二者都可作 `--from` / `--anchor` 入参:
|
|
159
|
+
|
|
160
|
+
- **冻结锚点轮目录** `training/runs/r176`(含 `reports/` 全量证据,v4 sampled 44 例)——本机跑过训练时用它;
|
|
161
|
+
- **入库压缩锚点** `training/anchors/r176.json`(40 例共享案例,逐例指标齐全)——`training/runs/` 被
|
|
162
|
+
gitignore,**干净克隆与 CI 上只有这一份**,锚点回归必须走它:
|
|
163
|
+
`node skills/card-skill-trainer/scripts/round_diff.mjs --from training/anchors/r176.json --to training/runs/<本轮>`。
|
|
164
|
+
|
|
165
|
+
与锚点无共享案例(全新批次)时 `promotionGate.passed = null`,并注明「只作盲测/基线,不构成锚点回归」:
|
|
121
166
|
|
|
122
167
|
| 门禁 | 目标 | 说明 |
|
|
123
168
|
|---|---|---|
|
|
124
169
|
| 回归 pass→fail | **0** | round_diff 状态迁移硬底线;任何 1 例即拒绝晋级 |
|
|
125
|
-
| 均值指标 | 不低于锚点 | fidelity/
|
|
170
|
+
| 均值指标 | 不低于锚点 | fidelity/position/structure/components 不得下降、pixel 不得上升(round_diff delta 表 / plan 的 degradedMeans) |
|
|
126
171
|
| 本轮 passRate | 批次门另计 | 新批次盲测允许低起点(如 v6 r200 = 4/30),靠迭代收敛而非门槛豁免 |
|
|
127
172
|
| duplicationFailures | 0 | 重复内容超限(重影)样本数 |
|
|
128
173
|
| lint / validate / render / upstream | 0 | 全零 |
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
>
|
|
132
|
-
> `
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
174
|
+
| 高掩膜 PASS | 需复核 | 掩膜 ≥25% 的通过案例不计入晋级证据(见「掩膜覆盖率护栏」) |
|
|
175
|
+
|
|
176
|
+
> 基线载体是**冻结锚点轮目录**(含 `reports/` 全量证据)+ **入库压缩锚点** `training/anchors/<round>.json`
|
|
177
|
+
> (P0-2 起:干净克隆与 CI 上唯一的锚点载体,`round_diff.mjs` / `plan_next_round.mjs` 都直接吃它)。
|
|
178
|
+
> 本 Skill 目录下的历史 `baselines/v3-r0*.json` 范式已废弃并删除(指标快照改由 summary.json + 压缩锚点承载)。
|
|
179
|
+
> 晋级 = 新轮成为下一冻结锚点候选,在 `training/plans/` 记录轮号与指标,并重新生成压缩锚点入库。
|
|
180
|
+
|
|
181
|
+
### 泛化盲测门(generalization gate)
|
|
182
|
+
|
|
136
183
|
每 **3 轮**锚点回归后(或每次晋级基线前),必须用**未参与修复的新批次数据集**(或 holdout / eval 分区)抽取 **不少于 24 例未见样本** 做盲测(如 v6 sampled 30 例):
|
|
137
184
|
|
|
138
185
|
| 门禁 | 目标 | 说明 |
|
|
@@ -142,171 +189,301 @@ v4 sampled 44 例:与历史锚点共享 40 例 + holdout 新增 4 例计为 ne
|
|
|
142
189
|
| 盲测 avgFidelity | ≥ 0.78 | 未见样本平均还原度不低于 78% |
|
|
143
190
|
| 锚点 vs 盲测差 | ≤ 10pts | 锚点 avgFidelity − 盲测 avgFidelity ≤ 0.10(防过拟合) |
|
|
144
191
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
>
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
`
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
192
|
+
目标值唯一来源是 `lib/scoring.mjs::GENERALIZATION_GATE`,机器判定:
|
|
193
|
+
`plan_next_round.mjs --run <锚点轮> --blind <盲测轮> --anchor <锚点>`(出 `generalizationGate.passed`)。
|
|
194
|
+
|
|
195
|
+
**固定跨批次晋级盲测集**(解决单批次 eval/holdout 只有 2 例、凑不出 24 例的问题):
|
|
196
|
+
用 `build_sample.mjs` 从 v6 + v7 全量池各抽代表,合并成 `training/datasets/blindset/train-set.jsonl`
|
|
197
|
+
(≥24 例,结构聚类去重后覆盖列表/表单/结果/媒体/空状态),晋级轮一律用它盲测,
|
|
198
|
+
并在 `training/plans/` 记录该盲测集的 provenance 与轮号。盲测集**不参与任何修复迭代**。
|
|
199
|
+
### 收敛检测与早停
|
|
200
|
+
|
|
201
|
+
当出现以下任一信号时,**停止脚本微调,转而修订 Skill 文档规则或范式**:
|
|
202
|
+
|
|
203
|
+
1. **边际收益递减**:连续 3 轮焦点集 avgFidelity 提升 < 1pt(0.01)。
|
|
204
|
+
2. **锚点升但盲测降**:锚点 avgFidelity 提升但盲测 avgFidelity 下降 → 判定过拟合,拒绝晋级。
|
|
205
|
+
3. **同一签名反复出现**:同一失败签名在 ≥ 3 轮中重复出现且未消除 → 说明脚本补丁无效,需升级 Skill 级别范式。
|
|
206
|
+
4. **盲测差扩大**:锚点−盲测差从 ≤5pts 扩大到 ≥10pts → 过拟合风险,强制回退。
|
|
207
|
+
|
|
208
|
+
以上 4 类信号由 `plan_next_round.mjs` 自动计算(信号名:`marginal-gain-below-1pt` /
|
|
209
|
+
`anchor-up-blind-down` / `same-signature-3-rounds` / `anchor-blind-gap-over-10pts`,另有 `pass-by-mask`),
|
|
210
|
+
任一触发即写出 `reports/convergence-report.json`。收敛触发后,Agent 必须在该报告基础上给出瓶颈分类和
|
|
211
|
+
Skill 级改进建议,而非继续打脚本补丁。
|
|
212
|
+
|
|
213
|
+
> 趋势口径:边际收益按**最近 ≤4 轮的共同案例集**算 avgFidelity 逐轮 delta(跨批次轮次案例集不同,
|
|
214
|
+
> 直接比均值是假信号);重复签名按 `--history`(默认自动扫 `training/runs/` 最近 8 轮)统计,
|
|
215
|
+
> 老报告没有签名字段时按当前尺子现算,保证跨轮可比。
|
|
216
|
+
|
|
217
|
+
### 视觉修正回路(模型在环)
|
|
218
|
+
|
|
219
|
+
当脚本化校正(`correctCardLayout` 的 X/Y 轴 padding 对齐)收敛后仍无法通过门禁时,启用模型多模态回路,遵循「模型视觉判断 > 脚本启发式」的优先级:
|
|
220
|
+
|
|
221
|
+
1. 对焦点集每例收集 `design.png`、`render.png`、`spec.json`、`schema.json` 与渲染元素盒 `elementBoxes`。
|
|
222
|
+
2. 模型逐区域比对设计稿与渲染图,输出**可执行的布局修正指令**(目标节点 + 属性 + 期望值 + 证据区域),写入 `visual-fix.jsonl`;指令只允许引用结构证据(坐标、尺寸、颜色、文本),禁止出现业务词硬编码。
|
|
223
|
+
3. 脚本按指令修改 schema 并重渲染,仅当 position / pixel / duplication 三项均不退化时才保留,否则回滚。
|
|
224
|
+
4. 同一修正模式在 ≥3 个案例中复现 → 抽象为通用规则回灌 `dsl-card-generator` 或 `sketch-spec-to-card`,并登记 `training/lessons/lessons.jsonl`。
|
|
225
|
+
5. 每轮视觉修正后必须复跑冻结锚点,防止局部修正引发全局回归。
|
|
226
|
+
|
|
227
|
+
> **lessons 反哺提案**:定期(建议每个训练批次收尾时)跑 `node training/tools/aggregate_lessons.mjs` 聚合 lessons.jsonl——重复签名(同一坑重复踩)、未落盘规则(按 targetFiles 给建议落点)、密集落盘点(规则密集文件需结构性审视)三类提案,人工逐条 yes/no 审批后落盘,工具本身不自动改任何 skill 文件。
|
|
228
|
+
|
|
229
|
+
## 当前基线与落地门
|
|
230
|
+
|
|
231
|
+
当前冻结锚点 = `training/runs/r176`(v4 sampled 44 例)/入库压缩锚点 `training/anchors/r176.json`(40 例共享)。
|
|
232
|
+
最近一次锚点回归 **r262 = 44/44 PASS,对 r176 0 例 pass→fail**(v7 焦点集双案例过门后收口);
|
|
233
|
+
r198 记录的共享 40 例均值为 fidelity 96.4% / pixel 3.8% / position 95.7% / structure 95.6%。
|
|
234
|
+
|
|
235
|
+
批次盲测基线:
|
|
236
|
+
|
|
237
|
+
- v5(转账二批次 17 代表)r199 = 14/17、avgFid 95.8%、avgPix 4.0%;
|
|
238
|
+
- v6(存款+理财 30 代表)r200 = 4/30、avgFid 81.7%——新布局族缺口,仍是泛化主战场
|
|
239
|
+
(见 `training/plans/v6-dataset-baseline.md`、`v6-iteration-plan.md`);
|
|
240
|
+
- v7(焦点集)r243→r262 逐例收敛:`945b562caad1f0f4` 散点带/段落壳/评分仪表盘通道落地后
|
|
241
|
+
pix 0.1348→0.0681、pos 0.532→0.905、comp 0.852;`86ae6d41957935d8` 渐变壳绑定修正后 pix 0.055。
|
|
242
|
+
对应规则见 `dsl-card-generator/references/generation_pitfalls.md §21-24` 与 lessons `r255-l01..l05` / `r261-l01`。
|
|
243
|
+
|
|
244
|
+
指标水位一律以最近一轮 `reports/summary.json` 为准;本节只固定「哪个轮次是锚点、哪个批次是主战场」。
|
|
245
|
+
|
|
246
|
+
> **干净克隆 / CI 上**:`training/runs/`、`training/datasets/` 都被 gitignore。锚点对账走
|
|
247
|
+
> `training/anchors/r176.json`;保真度软门禁走入库 fixture `training/fixtures/ui-drafts/`
|
|
248
|
+
> (`tools/regress-fidelity.mjs` 在 `UI/` 缺失时自动回退);数据集需用 `build_dataset.py`
|
|
249
|
+
> 从桌面导出重建,provenance 记在 `dataset-summary.json`。
|
|
250
|
+
|
|
251
|
+
历史演进(baseline JSON 范式时期,仅供追溯):
|
|
252
|
+
|
|
253
|
+
| 基线 | 平均还原度 | 最低 | 低于80% | 结构还原度 |
|
|
254
|
+
|---|---:|---:|---:|---:|
|
|
255
|
+
| v3-r050n (08/26) | 79.5% | 73.2% | 26 | 70.4% |
|
|
256
|
+
| v3-r052n (08/27) | 80.5% | 74.1% | 15 | 71.1% |
|
|
182
257
|
| v3-r058 (08/28) | 85.9% | 82.0% | 0 | 93.2% |
|
|
183
|
-
| 冻结锚点范式 (r176→r198) | 96.2%→96.4% | — | 0 | 95.4%→95.6
|
|
184
|
-
|
|
185
|
-
### 定向还原度迭代协议(r060 起)
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
258
|
+
| 冻结锚点范式 (r176→r198→r262) | 96.2%→96.4% | — | 0 | 95.4%→95.6%(r262 全量 44/44 PASS) |
|
|
259
|
+
|
|
260
|
+
### 定向还原度迭代协议(r060 起)
|
|
261
|
+
|
|
262
|
+
基线通过后不直接全量重训。每轮使用「冻结锚点(案例数以锚点载体为准:压缩锚点 40 例 / 冻结轮 44 例)
|
|
263
|
+
+ 低分焦点集 + 未见样本盲测」:
|
|
264
|
+
|
|
265
|
+
1. 焦点集用 `run_round.mjs --focus <上轮> [--focus-below 0.85] [--focus-limit N]` 自动选(失败例 +
|
|
266
|
+
低于阈值的「刚过线」样本,按还原度升序),或读 `plan_next_round.mjs` 的 `focus.caseIds`;
|
|
267
|
+
`<82%` 必须逐张多模态归因。
|
|
268
|
+
2. Agent 同时读取设计稿、渲染截图、`spec.json` 和 `schema.json`(`diagnose_case.mjs --out` 已把这些
|
|
269
|
+
证据与偏差表打包成 JSON),输出区域级 `agent-audit.jsonl`;结论必须包含失败类、通用规则候选、置信度和目标 Skill。
|
|
270
|
+
3. 修复优先级:可见媒体与重影 → 语义顺序与纵向节奏 → 背景/圆角/留白 → 未见样本泛化。
|
|
271
|
+
4. 缺失/状态错切图优先画板裁切(`cropSlice`,含宽条切图与纯矢量 logo 组;矩形内有文本叠加或背景级大矩形禁裁),裁切不可用才纯色近似并标记缺陷;弥散/光晕类纹理特事特办,计入局部还原度豁免。
|
|
272
|
+
5. 焦点样本通过后必须复跑冻结锚点全量;每 3 轮做不少于 24 例未见样本盲测(固定跨批次盲测集见上文)。
|
|
273
|
+
6. 晋级门、焦点 ID 和产物路径以 `training/plans/` 下最新 plan 与本轮 `reports/next-round-plan.json` 为准。
|
|
274
|
+
7. 新布局通道(如散点带 §21、段落壳归属 §22、行锚点/尾随切片 §23)落盘生成器后,同步 lessons.jsonl + generation_pitfalls/quickref/previewer_contract,并复跑冻结锚点确认 0 回归;通道判据只认几何/样式结构,不认业务词。
|
|
275
|
+
|
|
276
|
+
训练清单可记录样本 ID 和画板名作为证据;运行时代码、Skill 判定和校验器不得引用业务词、画板名或样本专属文案。
|
|
277
|
+
|
|
278
|
+
### 晋级落地检查清单
|
|
279
|
+
|
|
200
280
|
新一轮改动落地前必须满足:
|
|
201
281
|
|
|
202
282
|
1. 失败样本探针全部通过。
|
|
203
|
-
2. 冻结锚点全量回归 round_diff **0 例 pass→fail
|
|
283
|
+
2. 冻结锚点全量回归 round_diff **0 例 pass→fail**,且均值指标不退化、无新增失败签名
|
|
284
|
+
(`plan_next_round.mjs --anchor` 的 `promotionGate.passed = true`)。
|
|
204
285
|
3. validate/lint/render/upstream 失败数均为 0。
|
|
205
286
|
4. `git status --short -- src` 为空。
|
|
206
|
-
5. 批次轮 score_round:duplicationFailures = 0;成熟批次(v4/v5)另要求 passRate 趋势向上且残留失败逐例归因。
|
|
207
|
-
6. 若为晋级轮,盲测 24 例 passRate ≥ 85%,盲测 avgFidelity ≥ 78%,锚点−盲测差 ≤ 10pts。
|
|
208
|
-
7. 通用规则写入 `training/lessons/lessons.jsonl
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
287
|
+
5. 批次轮 score_round:duplicationFailures = 0;成熟批次(v4/v5)另要求 passRate 趋势向上且残留失败逐例归因。
|
|
288
|
+
6. 若为晋级轮,盲测 24 例 passRate ≥ 85%,盲测 avgFidelity ≥ 78%,锚点−盲测差 ≤ 10pts。
|
|
289
|
+
7. 通用规则写入 `training/lessons/lessons.jsonl`(新格式 `{lessonId, signature, failureClass, evidenceCases,
|
|
290
|
+
rule, targetFiles, status, round}`;`plan_next_round.mjs` 产的 `lesson-drafts.jsonl` 是待补 rule 的草稿),
|
|
291
|
+
并同步到对应 Skill 的 `SKILL.md` 或 `references/`;业务词、画板名和样本专属文案不得进入规则。
|
|
292
|
+
8. 通过后以新轮目录作为下一冻结锚点候选并登记 `training/plans/`,同时重生成压缩锚点入库
|
|
293
|
+
(`training/anchors/<round>.json`);未通过的候选规则保持 `candidate`,不修改正式 Skill 行为。
|
|
294
|
+
9. `npm run ci` 全绿(9 硬门禁:card-check / smoke-preview / verify-event-model / verify-model-expose /
|
|
295
|
+
magic-values / regress-data / unit-tests / mcp-doc-sync / lint-ratchet;另有 regress-fidelity、lint 两道软门禁):评分尺子改动被
|
|
296
|
+
`tools/tests/scoring.test.mjs` 直接拦截;lint 走棘轮(`tools/lint-baseline.json`,error 只减不增,
|
|
297
|
+
治理后 `node tools/lint-ratchet.mjs --update` 收紧)。
|
|
298
|
+
10. 掩膜 ≥25% 的通过案例已人工看图复核(`summary.json::highMaskCases` / plan 的 `pass-by-mask` 信号)。
|
|
299
|
+
|
|
300
|
+
评分器本身也要参与回归:组件语义升级(如 `Input` 正确承载金额)时,评分器必须把可编辑文本组件计入 text 维度;ListLayout 必须按数据项数展开模板内 Text/Image/Input/Button 计数,避免正确模板复用被当成组件丢失。
|
|
301
|
+
|
|
302
|
+
结构评分对轮廓直方图使用约 1.25% 尺寸的对称最近邻对齐窗口:1–2 像素渲染偏移不视为结构丢失,明显缺块、错位和错误背景仍会扣分。调整该容差必须同步复跑冻结锚点,不允许用放宽阈值掩盖还原缺陷。
|
|
303
|
+
|
|
304
|
+
像素对比额外记录 `bestAlignDy`(最佳纵向对齐偏移,仅诊断字段,不参与评分):用于区分「截图裁切/节奏误差」与「真实布局错误」。**禁止**用对齐搜索后的差异替代零偏移差异参与评分——实测(r125)偏移因案例而异(0 / -4 / -16px 并存),不存在可统一归一化的系统性裁切偏移,统一平移只会掩盖真实的纵向节奏缺陷。
|
|
305
|
+
|
|
306
|
+
布局自动校正覆盖 X/Y 两轴:`correctCardLayout` 按渲染元素与标注的偏差调整子节点的 `paddingTop`/`paddingLeft`(X 轴钳制 ±48px),仅当校正后 position 总分变好才保留,否则回滚 schema。
|
|
307
|
+
|
|
308
|
+
## 命令
|
|
216
309
|
|
|
217
|
-
|
|
310
|
+
### 运行前置(跨平台)
|
|
218
311
|
|
|
219
|
-
|
|
312
|
+
| 依赖 | 要求 | 缺失时的表现 |
|
|
313
|
+
|---|---|---|
|
|
314
|
+
| Node | ≥ 20(`package.json::engines`) | 动态 import / `node:test` 行为异常 |
|
|
315
|
+
| Python | python3 或 python + Pillow(`DSL_CARD_PYTHON` 可指定) | validate / build_dataset 全失败 |
|
|
316
|
+
| 系统 Chrome | 训练渲染的硬依赖;Windows 自动探测 `Program Files` / `Program Files (x86)` / `LOCALAPPDATA`,也可 `CHROME_PATH=<绝对路径>` | 全案例 `renderFailures`,报「未找到系统 Chrome」 |
|
|
317
|
+
| 离线预览产物 | `npm run build:skill-preview` → `skills/dsl-card-generator/vendor/preview/`(源是宿主 `card-editor/`) | 渲染白屏 / 截图为空 |
|
|
318
|
+
| 依赖安装 | `npm install`(pngjs 等;同时装好 `.githooks`) | `Cannot find package 'pngjs'` |
|
|
319
|
+
|
|
320
|
+
> Windows 注意:脚本内所有绝对路径动态 import 必须走 `pathToFileURL`(`importAbs` helper),
|
|
321
|
+
> 裸盘符路径会被 ESM 加载器当成 `d:` 协议 URL 抛 `ERR_UNSUPPORTED_ESM_URL_SCHEME`;
|
|
322
|
+
> Chrome 探测也不能只认正斜杠 + `which`(Windows 无 `which`,只有 `where`)。
|
|
323
|
+
> 找不到 Chrome 时会退化到 Edge(同为 Chromium/CDP),但**换浏览器必须重跑字体掩膜探针**,
|
|
324
|
+
> 否则 pixelDiff 口径漂移。
|
|
220
325
|
|
|
221
326
|
### 构建数据集
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
python skills/card-skill-trainer/scripts/build_dataset.py \
|
|
330
|
+
--src "<设计稿导出根目录>" \
|
|
331
|
+
--out training/datasets/v1 \
|
|
332
|
+
--max-cases 160
|
|
333
|
+
|
|
334
|
+
# 聚焦训练(提速首选):--src 可直接指单份 MeaXure 导出;--artboards 只构建指定画板
|
|
335
|
+
python skills/card-skill-trainer/scripts/build_dataset.py \
|
|
336
|
+
--src ~/Desktop/某设计稿导出 \
|
|
337
|
+
--out training/datasets/v7 \
|
|
338
|
+
--artboards 4,14 --no-artboard-dedup
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
- `--artboards`:1 起序号或画板名关键词(逗号分隔,可混用)。序号转 parse_meaxure 的 0 起
|
|
342
|
+
`--indices`、关键词走 `--only`;未选画板不进数据集。实测 47 画板整稿 → 2 画板:构建耗时降到 ~43s。
|
|
343
|
+
- `--src` 指向自带 index.html 的单份导出时,它自身即唯一 source(不必再指到父目录把同级稿子全卷进来)。
|
|
344
|
+
|
|
345
|
+
### 结构去重抽样(新批次必做)
|
|
222
346
|
|
|
223
347
|
```bash
|
|
224
|
-
|
|
225
|
-
--
|
|
226
|
-
--
|
|
227
|
-
--max-cases 160
|
|
348
|
+
node skills/card-skill-trainer/scripts/build_sample.mjs \
|
|
349
|
+
--dataset training/datasets/v6/train-set.jsonl \
|
|
350
|
+
--threshold 4 --force-include <历史失败案例Id>
|
|
228
351
|
```
|
|
229
352
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
--round r060 \
|
|
236
|
-
--strategy v3 \
|
|
237
|
-
--limit 48
|
|
238
|
-
```
|
|
353
|
+
设计稿里同一列表页的业务变体(布局/配色一致、只换文案)会重复训练同一族并让指标被大家族主导。
|
|
354
|
+
`build_sample.mjs` 用 dHash + 贪心聚类折叠近似重复,每族取中位代表,产出
|
|
355
|
+
`train-set.sampled.jsonl`(迭代轮用)与 `sampling-report.json`(族划分证据);
|
|
356
|
+
`--force-include` 保住历史失败/探针案例防回归漏盯。全量 `train-set.jsonl` 保留不动,里程碑验收轮仍用全量。
|
|
357
|
+
实例:v5 39 画板 → 28 case → **17 代表**;v6 → **30 代表**。
|
|
239
358
|
|
|
359
|
+
### 运行一轮
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
node skills/card-skill-trainer/scripts/run_round.mjs \
|
|
363
|
+
--dataset training/datasets/v3/train-set.jsonl \
|
|
364
|
+
--round r060 \
|
|
365
|
+
--strategy v3 \
|
|
366
|
+
--limit 48
|
|
367
|
+
```
|
|
368
|
+
|
|
240
369
|
常用开关:
|
|
241
370
|
|
|
242
371
|
- `--only <caseId[,caseId]>`:只跑指定案例(冒烟用)。
|
|
243
372
|
- `--only-failed training/runs/<上轮>`:只重跑上轮失败案例(修复验证快路径)。
|
|
373
|
+
- `--focus training/runs/<上轮>`:焦点集 = 上轮失败例 + 通过但低于 `--focus-below`(默认 0.85)的低分例,
|
|
374
|
+
按还原度升序;`--focus-limit N` 限流。会打印等价的 `--only` 清单。
|
|
375
|
+
- `--inherit training/runs/<上轮>`:把上轮「本轮不重跑」的案例报告与截图搬进本轮,使增量轮成为完整可比轮
|
|
376
|
+
(`reports/inherited.json` 记录来源)。继承轮可作门禁/回归对账,**不作冻结锚点载体**。
|
|
377
|
+
- `--resume`:续跑既有轮目录(已有报告的案例跳过,渲染会话懒启动);进程被 kill 或渲染假死后不必整轮重来。
|
|
244
378
|
- `--no-correct`:禁用布局校正器,裸测生成器真实水平(里程碑对照用)。
|
|
379
|
+
- `--no-summary`:跳过收尾自动汇总(默认自动调 `score_round.mjs --quiet`,直接打出 pass/avgFid/roundGate)。
|
|
245
380
|
- `--splits train,dev`:限定分区(迭代纪律见上文)。
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
`
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
381
|
+
- `--only` / `--only-failed` / `--focus` 三者互斥,同时传会直接报错而不是静默取其一。
|
|
382
|
+
|
|
383
|
+
渲染会话(Chrome + 预览 HTTP server)由 `skills/dsl-card-generator/scripts/render_card.mjs::createRenderSession`
|
|
384
|
+
持有,收尾 `close()` **必须能返回**:CDP `send()` 带 60s 兜底超时、WebSocket `close/error` 立即拒绝全部在途请求、
|
|
385
|
+
`server.close()` 2s 后强制 `closeAllConnections()`(Chrome 的 keep-alive 连接不会自己断)。
|
|
386
|
+
少了任一条,浏览器异常退出时会出现「全案例跑完、`reports/` 齐全,却卡在 finally 写不出
|
|
387
|
+
`review-queue.jsonl` / `summary.json`,node 进程 0% CPU 常驻」的假死(r202 实测),只能 `kill -9` 重跑整轮。
|
|
388
|
+
|
|
389
|
+
### 单案例诊断(支持批量)
|
|
254
390
|
|
|
255
391
|
```bash
|
|
256
392
|
node skills/card-skill-trainer/scripts/diagnose_case.mjs \
|
|
257
|
-
--run training/runs/
|
|
258
|
-
--case <
|
|
393
|
+
--run training/runs/r262 \
|
|
394
|
+
--case <caseId1,caseId2,...> \
|
|
395
|
+
[--dataset training/datasets/v7/train-set.jsonl] \
|
|
396
|
+
[--out training/runs/r262/reports/diagnosis.json]
|
|
259
397
|
```
|
|
260
398
|
|
|
261
|
-
产出 `<caseId>.side.png`
|
|
262
|
-
|
|
399
|
+
产出 `<caseId>.side.png` 并排图、门禁未达标维度(按缺口降序)、失败类归因、掩膜覆盖率、上游聚焦门、
|
|
400
|
+
像素热区直方图、元素偏差 Top10、偏差节点→生成器源码行(`__prov`)溯源与失败类建议;
|
|
401
|
+
`--out` 额外落一份机器可读 JSON,供多模态归因直接消费(不必解析终端输出)。
|
|
402
|
+
多案例共用一套渲染会话与一次生成器 import;截图缺失时跳过并排图而不是整条命令失败;
|
|
403
|
+
标注几何取「聚焦卡」的 elements(与评分同源,避免多卡画板下产出幻影偏差)。
|
|
263
404
|
|
|
264
405
|
### 轮间对比
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
node skills/card-skill-trainer/scripts/round_diff.mjs \
|
|
409
|
+
--from training/runs/r060 \
|
|
410
|
+
--to training/runs/r061
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
列出指标 delta、fail→pass 修复清单、pass→fail 回归清单;存在回归时 exit 1,
|
|
414
|
+
可作为提交前门禁(`--allow-regressions` 可豁免)。
|
|
415
|
+
`--from` / `--to` 都可以是压缩锚点文件(干净克隆唯一可用的基线):
|
|
265
416
|
|
|
266
417
|
```bash
|
|
267
418
|
node skills/card-skill-trainer/scripts/round_diff.mjs \
|
|
268
|
-
--from training/runs/
|
|
269
|
-
--to training/runs/r061
|
|
419
|
+
--from training/anchors/r176.json --to training/runs/r262 --json training/runs/r262/reports/anchor-diff.json
|
|
270
420
|
```
|
|
271
421
|
|
|
272
|
-
|
|
273
|
-
|
|
422
|
+
`--json` 出机器可读结论(含 `promotionBlockers`),可直接接 CI 或写进 plan;
|
|
423
|
+
裸开关(不带路径)时默认落 `<--to 轮>/reports/round-diff.json`,不会写进仓库根目录。
|
|
274
424
|
|
|
275
425
|
### 汇总报告
|
|
276
426
|
|
|
277
427
|
```bash
|
|
278
|
-
node skills/card-skill-trainer/scripts/score_round.mjs --run training/runs/
|
|
428
|
+
node skills/card-skill-trainer/scripts/score_round.mjs --run training/runs/r262 [--quiet]
|
|
279
429
|
```
|
|
280
430
|
|
|
281
|
-
|
|
431
|
+
run_round 收尾已自动跑过一次(`--quiet` 模式);单独重跑用于改完评分口径后刷新 summary。
|
|
432
|
+
除指标均值与 roundGate 外,还出 `gateFailureHistogram`(下一轮该修哪一维)、`failureClasses`
|
|
433
|
+
(修复落点路由)、`avgExclusionCoverage` / `highMaskCases`(靠掩膜过门的案例点名)。
|
|
434
|
+
|
|
435
|
+
### 下一轮计划(自动归因)
|
|
282
436
|
|
|
283
437
|
```bash
|
|
284
|
-
node
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
python3 training/tools/split_report.py <runDir> [topN] # 按 split 聚合指标并列出最差 N 例
|
|
438
|
+
node skills/card-skill-trainer/scripts/plan_next_round.mjs \
|
|
439
|
+
--run training/runs/r262 \
|
|
440
|
+
--anchor training/anchors/r176.json \
|
|
441
|
+
[--blind training/runs/r263blind] [--history auto] [--focus-below 0.85] [--focus-limit 12] [--json]
|
|
289
442
|
```
|
|
290
443
|
|
|
444
|
+
一条命令给出:失败聚类(失败类 + 主签名 + 未达标维度 + 缺切图/高掩膜/|dy| 证据 + **建议修复落点文件**)、
|
|
445
|
+
焦点集 `--only` 清单、锚点晋级门判定、盲测泛化门判定、跨轮重复签名与 4 类收敛信号、
|
|
446
|
+
可直接粘贴的下一轮命令、以及 `lesson-drafts.jsonl`(`status=candidate` 草稿,人工补 rule 后落盘)。
|
|
447
|
+
归因只认指标与标注缺陷证据,不认业务词。
|
|
448
|
+
|
|
449
|
+
### 训练设施工具(`training/tools/`,已入库)
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
node training/tools/aggregate_lessons.mjs # lessons 聚合 → 反哺提案(P-B 未落盘规则 / P-C 密集落盘点)
|
|
453
|
+
node training/tools/probe_font_metrics.mjs # 非标字体回退字宽探针 → training/reports/font-metrics.json(掩膜扩宽比)
|
|
454
|
+
node training/tools/analyze_position.mjs <round> [caseIdPrefix...] [--dataset <jsonl>] # 逐样本 spec 文本框 vs 渲染 elementBoxes 配对偏差(缺省扫 training/datasets/*/*.jsonl)
|
|
455
|
+
node training/tools/probe_offsets.mjs <cardsRoot> <cardId> <width> [captureHeight] # 实测渲染页 DOM 几何(padding / content box / 偏移)
|
|
456
|
+
python3 training/tools/split_report.py <runDir> [topN] # 按 split 聚合指标并列出最差 N 例
|
|
457
|
+
```
|
|
458
|
+
|
|
291
459
|
> `training/datasets/`、`training/runs/` 仍被 gitignore(体积 + 源稿版权)。数据集可复现性靠
|
|
292
460
|
> `dataset-summary.json` 的 `provenance`(sourceRoot / sourceNames / toolchainRev / 解析器参数)
|
|
293
|
-
> 与 `training/plans/`
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
461
|
+
> 与 `training/plans/` 的轮次记录;锚点回归靠冻结轮目录(`training/runs/r176`)**或入库压缩锚点**
|
|
462
|
+
> (`training/anchors/r176.json`,干净克隆唯一可用载体)。已入库的训练设施还有
|
|
463
|
+
> `training/tools/*`、`training/reports/font-metrics.json`、`training/fixtures/ui-drafts/`(保真度软门禁兜底稿)。
|
|
464
|
+
|
|
465
|
+
## 输出
|
|
466
|
+
|
|
297
467
|
```text
|
|
298
468
|
training/runs/<round>/
|
|
299
469
|
cards/
|
|
300
470
|
slices/
|
|
301
471
|
reports/
|
|
302
|
-
<caseId>.json ← 含
|
|
472
|
+
<caseId>.json ← 含 gateFailures / failureSignature / failureClass / exclusionCoverage
|
|
473
|
+
与 layoutCorrections / correctorRejected 校正明细
|
|
303
474
|
<caseId>.render.png ← 最终渲染截图
|
|
304
475
|
<caseId>.design.png ← 设计稿参考图
|
|
305
476
|
<caseId>.side.png ← diagnose_case 并排对比图(按需生成)
|
|
306
|
-
summary.json
|
|
307
|
-
|
|
477
|
+
summary.json ← 含 roundGate / roundGatePassed / correctorCoverage /
|
|
478
|
+
gateFailureHistogram / failureClasses / highMaskCases
|
|
479
|
+
summary.md ← 含晋级门禁表格、归因直方图与截图对比图廊
|
|
308
480
|
review-queue.jsonl
|
|
309
481
|
semantic-review.jsonl
|
|
482
|
+
inherited.json ← --inherit 轮:继承来源与案例清单
|
|
483
|
+
next-round-plan.json ← plan_next_round:聚类 / 焦点集 / 门禁判定 / 收敛信号
|
|
484
|
+
lesson-drafts.jsonl ← plan_next_round:lessons 新格式草稿(status=candidate)
|
|
485
|
+
convergence-report.json← 收敛/早停信号触发时产出
|
|
486
|
+
diagnosis.json ← diagnose_case --out:批量诊断的机器可读证据包
|
|
310
487
|
```
|
|
311
488
|
|
|
312
|
-
`summary.md`
|
|
489
|
+
`summary.md` 与 `next-round-plan.json` 是需要周期性查看的两份产物;如果所有门禁通过,可以完全不看。
|