可视化叙事网站交付
核心原则
先问清 → 出计划 → 独立审核 → 自核实 → 实测校正 → 分批实施 → 每批可部署。 任何“不卡顿”“观感好”这类无法脚本判定的验收语都是禁区:每条验收标准必须能被无头浏览器断言。
本 skill 的 6 个组成部分:
- 本文件:七阶段流程 + 提问清单 + 审核模板 + 汇报格式
references/verify-recipes.md:13 种运行时测量技术 + 坐标/管线陷阱references/pitfalls.md:22 条实测坑(现象→根因→修复→通用规则)references/animation-components.md:第三方 canvas 组件的集成套路(缓存键 / cleanup / 挂载条件 / 停帧验收)references/content-sourcing.md:数字必须有出处或明确标教学示意(科普/医学/数据类必读)assets/:long-stage.tsx+long-stage.css(长舞台三层结构)、tokens.css(双主题)、verify-skeleton.mjs.md(验收脚本骨架)
触发即读的对应关系:要接第三方动画组件 → 读 animation-components;页面有具体数字/科学结论 → 读 content-sourcing;其余按阶段顺序读。
阶段 1:先问,不许猜
需求存在任何未经证实的假设时,禁止写代码。把待定决策画成树,每轮只问前置条件已确定的;每个问题必须附推荐答案 + 理由,让用户能直接说 yes;能自己查证的(读文件、跑命令、查文档)不要问用户。
必问清单(按依赖顺序,可按项目裁剪):
- 主题具体是什么(领域/子领域/呈现角度)
- 给谁看(决定术语密度与容错度)——“评分人/评审视角”是隐性需求,必须主动挖:问“谁来判断它做得好不好”比问“写多深”有效
- 打开页面第一眼要让人看懂什么(一句话定调;给“数字冲击型/提问互动型/反差悬念型”候选)
- 数据来源:真实可溯源 / 教学示意 / 混合
- 视觉基调:深色沉浸 / 浅色专业 / 高对比
- 交付形态:单页 landing / 多章节长滚动 / 多页
- 要不要 3D(收益 vs 验收成本)
- 互动增强:长舞台 / 鼠标跟随 / 第三方动画组件
- 项目目录位置
- 用户提供的参考材料如何落地(源码集成 vs 只当视觉参考)
- 在线地址 / 部署方式
用户中途修订决策是正常的(例:浅色 → 双主题)。决策表要保留“原决策作废”记录,不要静默覆盖。
阶段 2:出计划,等审核
计划文件写到 docs/plan-<主题>.md 并入库。必须包含:
- 现状分析:改现有项目时每句话带
file:line;新建项目列文件清单 - 决策表 D1–Dn:每条写“为什么这么选”,不写“我打算这么做”
- 分批次:每批独立可部署、可回滚
- 验收标准必须脚本能判定:“不卡顿” → “rAF 帧间隔中位数 ≤33ms”;“观感好” → “相邻卡片 blur(3px) opacity .55”
- 明确“不做什么”:写清排除项,防止实施期膨胀
阶段 3:等明确确认
“嗯”“好”“行”视为含糊,再确认一次;“看着办”不算确认。
阶段 4:独立审核
派全新上下文的子代理审核计划。它不能只看计划,必须同时给它真实代码与验收脚本。
你正在审核一份尚未开始实施的计划。你的任务是找出问题,不是批准。
## 必读
- 计划文档:<路径>
- 真实代码:<项目根>,重点 <文件>
- 验收工具:<脚本路径>
## 按优先级检查
1. 事实准确性(最高价值):每一处 file:line 是否正确?每条关于现有行为的论断是否成立?错了的引用真实代码行反驳。
2. 完整性:声称实现 N 个决策,逐个检查是否都有任务落实。
3. 内部矛盾:A 节承诺的,B 节是否禁止了?
4. 具体技术风险:列出 3-5 个本任务最可能出错的点。
5. 遗漏:计划没写、实施者必须自己发明的东西有哪些?
6. 验收可检验性:每条标准能否被客观判断?哪些是模糊话?
7. 批次顺序:有没有批次依赖后面的批次?有没有东西不属于任何批次?
## 输出
编号列表,每条:严重程度(BLOCKING/MAJOR/MINOR)、位置、错在哪(带证据)、怎么修。
最后给结论:能否进入实施?
不要修改任何文件。不要为了礼貌而批准——什么都没找到的审核是失败的审核。
阶段 5:审核意见必须自己核实
子代理会犯错。 逐条去代码里验证,确认成立才改。预设“预期有一条是它自己错的”。
已观察到的两次真实结果:
- 一次审核 16 条意见全部成立(7 MAJOR + 9 MINOR,其中 3 条是“验收机制本身失效”——断言恒真或永不失败)
- 另一次它把 A 组件的 idle 判定安到 B 组件头上,靠读源码行号识破
阶段 6:实测校正
审核代理靠读代码推断,读不出运行时尺寸/帧率/合成行为。用无头浏览器量,所有写进文档的数字必须是实测值。
见 references/verify-recipes.md。
阶段 7:分批实施
每批结束:跑完整验收 → git tag → 提交。commit 信息写“改了什么、为什么、实测数据”。
汇报固定三段:
- 做了什么:文件清单 + 实测数据(不是“已完成”,而是
pinTop=68.0、travel 偏差 0.0px) - 还差什么
- 发现了什么:计划错还是代码错,错在哪一行
验收体系的最小构成(本项目实测 45 断言 / 7 单测)
| 层 | 工具 | 管什么 |
|---|---|---|
| 类型 | tsc --noEmit | 类型完整性。vitest 全绿 ≠ 能构建,esbuild 剥类型 |
| 单元 | vitest run | 数据诚实性(出处字段非空、两类必须共存)、纯函数 |
| 运行时 | scripts/verify.mjs(puppeteer-core + 系统 Chrome) | 布局溢出、对比度、帧率、动画状态、降级分支 |
| 交付 | npm run build | 真实产物能构建 |
断言必须能失败。 写完每条断言后反向改一次代码确认它 FAIL,否则你不知道它是恒真还是真在测。
跨视口的断言必须走 setViewportSettled。 page.setViewport 只保证视口尺寸已提交,不保证 reflow 完成;紧接着读 scrollWidth 会拿到缩窄前的旧值,表现为偶发 FAIL(见 references/pitfalls.md 第 21 条)。这类偶发问题只有重复跑才暴露——单次全绿不能当验收证据。
常见误区
| 误区 | 实际 |
|---|---|
| “单元测试过了就能交付” | esbuild 剥类型,tsc 报错时 vitest 仍全绿 |
| “截图 diff 能测所有视觉变化” | headless 截图管线可能不捕获 DOM 重绘,只捕获 canvas 纹理 |
| “轮询等待 500ms 够了” | scroll-behavior:smooth + scrub:1 都是异步的,必须显式 instant + 显式轮询到条件成立 |
| “响应式就是改 viewport 测一遍” | pin/触摸/CDP 状态会跨用例污染,必须新开 page 或新开浏览器进程 |
| “reduced-motion 就是关动画” | 关动画但信息必须一条不少,要断言文本量不减 |
与其它 skill 的关系
- 视觉方向/反 AI 味:
frontend-design、design-taste-frontend - 计划与审核纪律:
writing-plans、plan-sds-review - 缺陷定位:
systematic-debugging - 完成后验证:
verification-before-completion
本 skill 只补它们没有的部分:运行时数据的采集口径、可视化专有的坑、长滚动叙事的结构。