ss-verify

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Verify (look at it, don't just read it)

验证(亲眼查看,而非仅阅读代码)

Read
.styleseed/effective-rules.md
and
.styleseed/manifest.json
; invoke
/ss-resolve
or
$ss-resolve
first when they are missing or stale. Judge pixels against that compiled method. A lock value cannot excuse a core failure, and a recipe/profile cannot replace the output grammar.
/ss-score
reads the code and scores it. But some of the worst "AI-made" tells never appear in source — they only exist in pixels: a hero that doesn't actually dominate, a lower third of dead whitespace, cramped cards, a web font that silently failed to load and fell back to Times, two colors that look like two accents once rendered, text that's unreadable on its real background. A human sees these in half a second; a code-reading gate misses all of them.
/ss-verify
closes that gap: it renders the UI, screenshots it, and you look at the image — then score the same StyleSeed gate against what you see, fix, and re-render. This is the gate that most predicts whether a real user will say "this looks designed."
Run it as the final gate after
/ss-score
passes — code-clean is necessary but not sufficient; pixel-clean is the real bar.
阅读
.styleseed/effective-rules.md
.styleseed/manifest.json
;当文件缺失或过时,先调用
/ss-resolve
$ss-resolve
。对照编译后的规则判断像素效果。锁定值不能掩盖核心缺陷,配方/配置文件也无法替代输出语法。
/ss-score
读取代码并打分。但一些最明显的“AI生成”问题从未出现在源码中——它们只存在于像素里:本应突出的主视觉并未占据主导地位、底部三分之一区域是无效空白、卡片布局拥挤、网页字体加载失败并回退到Times字体、渲染后看起来像两种强调色的颜色、在实际背景上无法辨认的文本。人类一眼就能发现这些问题,但仅读取代码的关卡会全部遗漏。
/ss-verify
填补了这一空白:它会渲染UI、截取屏幕截图,然后你查看截图——接着对照所见内容对同一StyleSeed关卡打分、修复并重新渲染。这个关卡最能预测真实用户是否会觉得“这看起来是经过设计的”。
应在
/ss-score
通过后作为最终关卡运行——代码规范是必要条件但不够充分;像素级的规范才是真正的标准。

When NOT to use

何时不使用

  • Nothing renderable yet (pure logic/config, or a component with no host page) → use
    /ss-score
    .
  • No way to render at all (no browser, no Playwright, headless blocked) → say so, fall back to
    /ss-score
    , and tell the user the visual gate was skipped. Never claim you verified visually if you didn't actually see a screenshot.
  • A quick pre-commit pass →
    /ss-lint
    .
    /ss-verify
    is heavier (it boots a renderer).
  • 尚无可渲染内容(纯逻辑/配置,或无宿主页面的组件)→ 使用
    /ss-score
  • 完全无法渲染(无浏览器、无Playwright、无头模式被阻止)→ 如实说明,回退到
    /ss-score
    ,并告知用户已跳过视觉关卡。若未实际查看截图,绝不能声称已进行视觉验证。
  • 快速的提交前检查 → 使用
    /ss-lint
    /ss-verify
    更耗费资源(它会启动渲染器)。

Step 1 — Render it through the active adapter

步骤1 — 通过当前适配器渲染

For
social-carousel
,
slide-deck
,
document-report
, or
single-frame
, use the companion renderer and open every required exported frame/page at readable resolution. Verify dimensions, crop/safe zones, font availability, asset placement, and the export manifest. Do not force a browser workflow onto a PIL, slide, PDF, or image renderer.
For
product-ui
, get a real screenshot in priority order:
A. Running project (Next / Vite / etc.) — the normal case.
  1. Start the dev server in the background (
    npm run dev
    /
    pnpm dev
    / framework command); wait for the ready line and capture the port.
  2. Screenshot the route with headless Chromium via Playwright. If the project has
    playwright
    in
    node_modules
    , use it; else use a globally cached Chromium. Minimal script:
    js
    import { chromium } from "playwright";           // or an absolute path into node_modules
    const b = await chromium.launch();
    const c = await b.newContext({ viewport: SURFACE, deviceScaleFactor: 2 });
    const p = await c.newPage();
    await p.goto(URL, { waitUntil: "networkidle" });
    await p.evaluate(() => document.fonts.ready);      // don't shoot before fonts load
    await p.waitForTimeout(400);
    await p.screenshot({ path: OUT, fullPage: true });
    await b.close();
    Surface viewports: mobile
    {width:390,height:844}
    · desktop
    {width:1440,height:900}
    . Pick from the lock's
    Surface
    , or
    --surface
    .
  3. If a browser MCP (claude-in-chrome) is available instead, navigate + screenshot with that.
B. Static HTML file → open it directly with
file://…
and screenshot (same script).
C. Isolated component (no host page) → render it into a minimal throwaway page that imports the component with realistic props, then screenshot that.
Then actually READ the screenshot back (Read the PNG). You must see it. Shoot at
deviceScaleFactor: 2
so text is crisp enough to judge.
对于
social-carousel
slide-deck
document-report
single-frame
,使用配套渲染器,以可读分辨率打开所有必需的导出帧/页面。验证尺寸、裁剪/安全区域、字体可用性、资源位置和导出清单。不要将浏览器工作流程强制应用于PIL、幻灯片、PDF或图像渲染器。
对于
product-ui
,按优先级获取真实截图:
A. 运行中的项目(Next / Vite / 等)——常规情况。
  1. 在后台启动开发服务器(
    npm run dev
    /
    pnpm dev
    / 框架命令);等待就绪提示并记录端口。
  2. 通过Playwright使用无头Chromium截取路由截图。若项目的
    node_modules
    中包含
    playwright
    ,则直接使用;否则使用全局缓存的Chromium。最简脚本:
    js
    import { chromium } from "playwright";           // 或指向node_modules的绝对路径
    const b = await chromium.launch();
    const c = await b.newContext({ viewport: SURFACE, deviceScaleFactor: 2 });
    const p = await c.newPage();
    await p.goto(URL, { waitUntil: "networkidle" });
    await p.evaluate(() => document.fonts.ready);      // 字体加载完成前不要截图
    await p.waitForTimeout(400);
    await p.screenshot({ path: OUT, fullPage: true });
    await b.close();
    表面视口: 移动端
    {width:390,height:844}
    · 桌面端
    {width:1440,height:900}
    。从锁定的
    Surface
    --surface
    参数中选择。
  3. 若有浏览器MCP(claude-in-chrome)可用,则使用它导航并截图。
B. 静态HTML文件 → 直接用
file://…
打开并截图(使用相同脚本)。
C. 独立组件(无宿主页面)→ 将组件渲染到一个导入了该组件并传入真实属性的极简临时页面中,然后截取该页面的截图。
然后实际查看截图内容(读取PNG图片)。你必须亲眼看到它。设置
deviceScaleFactor: 2
以确保文本足够清晰,便于判断。

Step 2 — Score what you SEE (the visual gate)

步骤2 — 对所见内容打分(视觉关卡)

Look at the image and run the StyleSeed gate perceptually. These are the checks that need eyes, not source:
□ Squint test    — blur your focus / imagine it at 50%. Does it still read "AI-generated"?
                   (bland gradient, pill button + generic sans, icon-chip row, even flat grid) → FAIL
□ Focal          — does ONE element actually dominate at a glance? If your eye lands nowhere,
                   or on an all-even grid, the focal point failed regardless of what code intended
□ Balance        — dead whitespace (a lower third of empty), or cramped/colliding elements?
                   Is the visual weight distributed, or all top-left / all-centered?
□ Fonts loaded   — is the intended typeface actually rendering, or a Times/Arial fallback?
                   (a silent font-load fail is a top "looks cheap" tell — invisible in code)
□ One accent (seen) — count the hues you actually SEE. Two things competing for "the color" = FAIL,
                   even if the code named one token
□ Contrast (seen) — any text you have to strain to read on its real rendered background?
                   Light-grey-on-white labels, low-contrast on a colored/照片 panel
□ Rhythm/optics  — are edges aligned, gaps consistent, cards optically even? Off-by-a-few-px
                   misalignments that read as "sloppy" but pass a code check
□ Type scale fit — on desktop, does the body text look too small for the canvas? does the hero
                   feel undersized? (the surface-scale tell, judged by eye)
□ Grammar fit   — does the screen visually serve the selected grammar's user job, attention
                   model, composition, density, action hierarchy, and characteristic tells?
□ Recipe fit    — do geometry, containment, controls, collections, navigation, density, and
                   motion visibly match the selected recipe rather than the old universal soft-card look?
                   Would the same layout still appear if the product changed? If yes, FAIL
□ Motion (if any) — capture before/after or a mid-transition frame; is it purposeful, or the
                   "cheap fade/bounce on everything" tell? does it block the first read?
查看图片,凭视觉感知运行StyleSeed关卡。以下检查需要人工视觉,而非源码分析:
□ 眯眼测试    —— 模糊视线 / 想象画面缩小到50%。它看起来仍像“AI生成”的吗?
                   (平淡渐变、胶囊按钮+通用无衬线字体、图标芯片行、均匀扁平网格) → 失败
□ 焦点          —— 一眼望去,是否有一个元素真正占据主导地位?如果你的目光无处停留,
                   或落在一个完全均匀的网格上,无论代码意图如何,焦点设置都失败了
□ 平衡        —— 是否存在无效空白(底部三分之一区域为空),或元素拥挤/重叠?
                   视觉重量是否分布均匀,还是全部集中在左上角/居中?
□ 字体加载完成   —— 预期的字体是否实际渲染,还是回退到Times/Arial?
                   (无声的字体加载失败是“看起来廉价”的典型特征——在代码中无法察觉)
□ 单一强调色(视觉可见)—— 数一下你实际看到的色调。有两个元素争夺“主色调”的地位 = 失败,
                   即使代码中只定义了一个颜色令牌
□ 对比度(视觉可见)—— 是否有文本在实际渲染的背景上需要费力才能辨认?
                   浅灰色文字配白色背景、彩色/照片面板上的低对比度文本
□ 韵律/视觉对齐  —— 边缘是否对齐、间距是否一致、卡片视觉上是否均匀?几像素的偏差
                   会让人觉得“草率”,但代码检查可能无法发现
□ 字体大小适配 —— 在桌面端,正文文本相对于画布是否太小?主视觉是否显得尺寸不足?(通过视觉判断的表面尺寸问题)
□ 语法适配   —— 屏幕视觉上是否符合所选语法的用户目标、注意力模型、布局、密度、操作层级和典型特征?
□ 配方适配    —— 几何布局、容器、控件、集合、导航、密度和动效是否明显符合所选配方,而非旧版通用软卡片样式?
                   如果产品更换,布局是否仍保持不变?若是,则失败
□ 动效(如有)—— 截取过渡前后或过渡中的画面;动效是否有明确目的,还是“所有元素都廉价淡入/弹跳”的典型问题?它是否影响首次阅读?

Step 3 — Render states or sequence variants too

步骤3 — 同时渲染状态或序列变体

The happy-path screenshot hides the most common real-world failure: no empty / loading / error state. Where the surface has a data view, render those variants (a query param, a mock, a forced prop, or temporarily emptying the data) and screenshot each. A blank white void for "no data" is a fail you can only catch by looking at the empty state. (Static marketing pages with no data surface → N/A, note it.)
For sequential artifacts, inspect the cover/first frame, every content frame, and close/CTA as a set: continuity, progression, one message per frame, repeated-template fatigue, source labels, folios, and safe-zone survival. For documents/decks, inspect every page/slide plus a representative thumbnail or overview view.
常规路径的截图会隐藏最常见的真实场景缺陷:没有空状态/加载状态/错误状态。若界面包含数据视图,渲染这些变体(通过查询参数、模拟数据、强制属性或临时清空数据)并分别截图。“无数据”时显示空白页面是只能通过查看空状态才能发现的失败。(无数据界面的静态营销页面 → 不适用,需注明。)
对于序列工件,检查封面/第一帧、所有内容帧以及结尾/CTA帧的集合:连续性、递进性、每帧一个核心信息、重复模板疲劳、来源标签、页码和安全区域适配。对于文档/幻灯片,检查每个页面/幻灯片以及代表性的缩略图或概览视图。

Step 4 — Fix, re-render, repeat

步骤4 — 修复、重新渲染、重复

For each visual failure, fix the code, then re-render and look again — don't assume the fix worked from the diff (the whole point is that code ≠ pixels). Loop up to ~3×. Present only when the screenshot passes, with the final image, the effective rule set, a one-line "fixed: …", and the gate result.
针对每个视觉缺陷,修复代码,然后重新渲染并再次查看——不要假设代码差异就能确保修复有效(这个技能存在的意义就是源码与像素效果存在差异)。循环最多约3次。仅当截图通过后再提交,附上最终图片、有效规则集、一行“已修复:……”以及关卡结果。

Rules

规则

  • You must actually see the rendered artifact. No render, no visual verdict — fall back to
    /ss-score
    and say the visual gate was skipped. Never fabricate "looks good."
  • Re-render after every fix. The reason this skill exists is that source and pixels diverge; verifying a visual fix by reading the diff defeats it.
  • Both gates, in order:
    /ss-score
    (code) first to catch structural issues cheaply, then
    /ss-verify
    (pixels) as the final bar.
    /ss-build
    runs code-gate in its loop; finish a renderable screen with
    /ss-verify
    .
  • Clean up: stop the dev server you started; delete any throwaway harness/mock files.
  • Shoot at 2× and at the locked surface's viewport — judging a desktop app on a 390px shot (or vice-versa) invalidates the type-scale and balance checks.
  • 必须实际查看渲染后的工件。 无法渲染则无法给出视觉结论——回退到
    /ss-score
    并说明已跳过视觉关卡。绝不能编造“看起来不错”的结论。
  • 每次修复后重新渲染。 这个技能存在的原因是源码与像素效果存在差异;通过查看代码差异来验证视觉修复毫无意义。
  • 两个关卡按顺序执行: 先运行
    /ss-score
    (代码关卡)以低成本发现结构问题,再运行
    /ss-verify
    (像素关卡)作为最终标准。
    /ss-build
    在其循环中运行代码关卡;完成可渲染界面后需运行
    /ss-verify
  • 清理工作: 停止你启动的开发服务器;删除所有临时测试 harness/模拟文件。
  • 以2倍分辨率截图并使用锁定的表面视口——在390px截图上判断桌面应用(反之亦然)会使字体大小和平衡检查失效。