网站设计审计 → 线框图 → 决策账本
目的
将本地克隆的网站转化为:(1) 哈希证据固定到 git commit,(2) 每条发现引用一条规则并指向可能的源文件,(3) Figma 中的现状和目标线框图,(4) 解释每次更改的决策记录,(5) 人工审批记录,以及 (6) 针对批准的决策的实施简报,由 Claude Code 或 Codex 在单独会话中执行。git 账本是最权威的来源。Figma 是其投影。此技能负责设计和记录;它从不编辑网站的源代码。
预期工作流程
- 学生克隆其站点的仓库(来自 GitHub,或 Vercel 项目部署的仓库)并在本地运行。学生应具有 Figma MCP 的教育版访问权限。
- 此技能从本地开发服务器捕获数据、进行审计,并在 Figma 中构建线框图。
- 人工分类发现、审查决策并批准。
- 此技能为每个批准的决策编写交接简报。Claude Code 或 Codex 在其自己的分支上实施每个决策。此技能重新捕获以进行验证。
命令
技能文件夹有一个命令 fwd 和一个 CLAUDE.md,其中说明了如何应答。当用户输入 help、check、init 或 tutorial 时,请遵循 CLAUDE.md:
help运行fwd help(设置检查加一个下一步)并在 Figma 工具存在时运行whoami以获取座位信息。先处理缺失项;提供一个下一步;不为学生做任何更改。tutorial运行七步初学教程(重新设计你的首页)。这是该技能自身的阶段,逐步驱动。fwd approve|reject|defer <D-id>由学生在自己的终端中运行。它会写入审批文件和账本事件。不可协商规则 1 适用:永远不要运行它,永远不要写入audit/approvals/。fwd ledger verify检查哈希链以及每个审批文件是否与账本匹配。
不可协商规则
- 只有人可以将决策设置为已批准、已拒绝或已推迟,或重新打开决策。切勿写入这些状态。切勿写入
audit/approvals/中的文件。 - 每条发现都引用来自
audit/rulebook/rules.yaml的rule_id。没有规则,就没有发现:将其作为observation记录给人类。 - 发现标签遵循规则层级:规范性 →
failure,启发式 →concern,内部 →deviation。切勿将启发式发现称为 failure。切勿对启发式发现使用通过/未通过图标或词语(✅ ❌ "violated")。 - 现状帧与其目标帧之间的每个差异都至少带有一个决策 ID。标记未标记的差异;不要忽略它们。
- 切勿编辑
00 As-Is页面。切勿修改或删除技能未创建的节点。仅触及技能自身类别中的注释,并且始终读取-合并-写入。 - 切勿设置开发模式状态(准备开发/已完成)。切勿解析或删除人工评论。
- 在人员保存了命名的基线版本并记录其 ID 之前,不得向现有 Figma 文件进行写入。例外:本次运行自身创建的 Figma 文件。它开始时是空的,因此空文件本身就是其基线;在
capabilities.json中记录。 - 仅从用户拥有或有权限处理的仓库的本地克隆、从 localhost 提供服务的站点、或者当用户提供其 URL 时来自同一仓库的已部署站点或 Vercel 预览版进行捕获。切勿捕获、注入脚本或剥离第三方实时站点的安全标头。
intent.yaml必须记录仓库和固定的 commit。 - 切勿覆盖先前的发现帧或更早的运行输出。重新运行会创建一个新的版本化帧(请参阅阶段 7)。切勿通过图层名称、填充颜色或文本启发式方法定位您自己的节点;使用账本中记录的节点 ID。
- 切勿编辑站点的源代码。实施仅发生在单独的 Claude Code 或 Codex 会话中,基于已批准决策的交接简报。
目录布局
audit/
intent.yaml # 人工填写(阶段 0)
rulebook/rules.yaml # 人工确认(阶段 1)
schema/ # finding, decision, approval, event 模式
runs/R-YYYYMMDD-NN/
capabilities.json # 本次运行实际能做什么
manifest.json # 捕获哈希和状态
captures/{width}/ # screenshot.png, dom.html, axe.json, checks.json, skeleton.json
findings.json
decisions/D-NNNN.json
approvals/A-NNNN.json # 仅人工操作
handoff/ # 实施简报,仅限已批准的决策
README.md # 实施代理的共享规则
D-NNNN.md # 每个已批准决策一个简报
ledger.jsonl # 仅追加,哈希链事件
站点的克隆位于 audit/ 外部(位于 local_path)。此技能读取它,但从不写入它。audit/ 可以放在同级文件夹或其自己的分支中,因此审计记录永远不会与站点提交混合。
阶段 0 — 意图(门 G0)
如果 audit/intent.yaml 缺失或具有空的必填字段,请以对话方式一次一两个地询问缺失的字段。在用户填写每个必填字段之前,不要捕获、评估或写入任何内容。如果用户尚未克隆仓库,请在其自己的代码块中给他们确切的 git clone 命令(对于 Vercel 项目,是它部署的 GitHub 仓库)并等待。
repo: "" # 必需:站点的 GitHub URL(或 Vercel 项目)
local_path: "" # 必需:本地克隆的路径
commit: "" # 必需:审计所固定的 commit SHA
dev_command: "" # 必需:例如 "npm run dev"
dev_url: "http://localhost:3000"
routes: [] # 必需:要审计的路径,例如 ["/", "/apply"]
ownership: "" # 必需:"own repo",或谁何时授予的权限
implementer: "" # 必需:"claude-code" 或 "codex"
conformance_target: "WCAG 2.2 AA"
breakpoints: "derive" # "derive" 从站点 CSS 派生,或一个宽度列表
house_rules: "" # 设计系统 token 的路径,或 "none"
figma_file: "" # Figma 阶段必需;空白 = JSON-only 模式
approvers: [] # 必需:姓名和角色
out_of_scope: []
阶段 1 — 模式(门 G1)
总结规则手册(按层级和模式划分的规则计数)和记录模式。要求用户确认或编辑。记录一个 schema.confirmed 账本事件,包含用户的姓名和日期。未经确认不得继续。
运行时能力探测
在阶段 2 之前,写入 capabilities.json:
- 存在哪些 Figma MCP 工具(
use_figma、generate_figma_design、html_to_figma、get_metadata、get_screenshot、generate_diagram、upload_assets)。 whoami结果:拥有figma_file的计划上的座位类型。如果无法进行写入,则设置mode: json-only并为本次运行跳过 Figma 写入。学生应具有教育版计划访问权限;仍然记录实际的座位和计划,而不是假设,并记录任何速率限制错误。- 本地环境:Node 和包管理器版本,
dev_command是否启动,以及local_path的工作树是否干净且位于commit。 - 在任何
use_figma调用之前加载 Figma 的figma-use技能。 - 读取实时的
use_figma工具模式,并记录它是否接受skillNames参数。一个可比较的 Figma 技能(Throughline)每次调用都会传递skillNames: "throughline"。如果参数存在,每次调用use_figma时都传递skillNames: "figma-webdesigner";如果不存在,则记录skillNames: unsupported。 - 从第一次运行(2026-11-07,完整学生席位)得知,重新验证而不是假设:
setSharedPluginData有效;addAnnotationCategoryAsync和node.annotations(带有labelMarkdown和categoryId)有效;figma.saveVersionHistoryAsync不受支持,因此代理永远无法创建基线版本;figma.root.name不可设置,因此无法通过 API 重命名文件。如果其中任何一个现在失败,则在帧名称中携带决策 ID 为⟦D-0007⟧加上注释,并记录结果。 - 调用
create_new_file时,为站点命名 Figma 文件(例如jobs.humanitarians.ai);之后无法重命名。页面是阶段(00 Kit & Legend、01 As-Is Wireframes、02 To-Be Wireframes);帧是page / width / as-is|to-be / state。
use_figma 脚本约定
此技能通过 use_figma 发送的每个脚本都必须遵循以下规则:
- 等高兄弟节点需要在每个子节点上设置
layoutSizingVertical = 'FILL'(并且当父节点拥抱其高度时,单独使用layoutAlign = 'STRETCH'是不够的。中心或表格单元格中必须换行的文本需要textAutoResize = 'HEIGHT'和宽度。 - 先处理字体。 在创建或编辑任何文本之前,在一个
Promise.all顶部为脚本使用的每种字体样式(包括 Italic 和 Medium,如果使用)调用figma.loadFontAsync。 - 在设置父子关系后设置尺寸。 将每个节点附加到其父节点,然后设置
layoutSizingHorizontal和layoutSizingVertical。仅使用记录的属性名称(cornerRadius,而不是corner);未知属性会被静默忽略。 - 返回写入回执。 脚本必须返回一个对象,其中包含
createdNodeIds和mutatedNodeIds(两者始终诚实地填充;仅当没有发生这种事情时才使用空数组),加上frameId、stamped(是否写入了插件数据)和pageId。 - 将回记录入账本。 每次调用后,追加一个包含回执、运行 ID、涉及的决策 ID 和
version_before的figma.write事件。后续阶段通过这些 ID 查找技能拥有的节点,从不通过名称或颜色。 - 变更前状态。 如果脚本更改任何现有节点(技能创建的节点上的注释、文本、填充),在回执中返回以前的值,以便账本可以记录它们。不允许覆盖而没有记录变更前状态。
- 大声失败。 无静默成功。如果查找未找到任何内容,则返回一个列出找到内容的错误;切勿将无操作报告为成功。
阶段 2 — 捕获
- 准备克隆。确认
local_path位于commit且工作树干净(如果不是,记录dirty: true并停止询问),安装依赖项,启动dev_command,并确认dev_url响应。在manifest.json中记录 commit SHA、dirty 标志和 Node 版本。不修改任何源文件。如果项目需要不存在环境变量或机密,请询问用户;切勿自行创造。 - 从仓库自身的配置(Tailwind 配置、CSS 自定义媒体、框架主题)以及站点的计算 CSS 媒体查询中派生断点(除非意图列出了宽度)。在 320、每个断点减一和断点处以及一个大的桌面宽度处进行捕获。
- 每个宽度:全页截图、DOM、axe-core 结果(标签 wcag2a、wcag2aa、wcag21aa、wcag22aa)、溢出检查、目标几何检查、结构骨架(地标、标题、带有边界框的交互集群)。
- 记录捕获状态(同意横幅、身份验证、变体)以及
manifest.json中每个文件的 SHA-256。 - 追加一个
capture.completed事件。
阶段 3 — 测量
运行自动化和辅助检查。自动化结果直接成为发现。辅助结果成为具有 mode: assisted 和 triage: null 的发现;注意可能适用的例外(间距、内联、等效、基本、数据表)。
源码映射。 对于每条发现,在克隆中搜索元素的源代码(其文本、类名、组件名称或数据属性)并记录 source: {file, line, confidence}。这是尽力而为:对于猜测使用 confidence: low,如果未找到位置则省略 source,而不是声称找到了位置。这些是给实施者的提示,而不是指令。
阶段 4 — 评估
运行启发式遍历。对于每条发现记录:
rule_id、定位器、证据路径和哈希- 严重性 0–4(Nielsen:频率、影响、持续性)
- 置信度(高/中/低)
scope:single-section、cross-section、component、interaction之一- 一行说明证据显示的内容
范围指南:
single-section:问题位于一个页面的一个块内。cross-section:问题仅出现在块、页面或宽度之间(优先级顺序与视觉顺序、不一致的模式、页面间变化的导航)。有意寻找这些问题;它们通常是最重要的,并且在逐节审查时最容易遗漏。component:一个可重用元素无论出现在哪里都表现得或看起来不一致。interaction:问题在于状态、流程或行为,而不是静态布局。
对于长页面,从其自己的截图评估每个部分并注意 y 位置;然后单独执行一次跨部分发现的遍历。仅包括有足够可见证据的规则;跳过无法从捕获中评估的规则,而不是猜测。将自己视为一个评估者;在发现摘要中说明。
门 G2 — 分类
按严重性分组呈现发现,然后按页面分组,以表格形式呈现:ID、规则、标签、范围、页面/宽度、严重性、置信度、一行证据。要求用户接受、拒绝或重新评分。将每个分类调用记录为归于用户的账本事件。仅接受的发现继续前进。
阶段 5 — Figma 基线(门 G3)
- 通过
generate_figma_design(或html_to_figma)将现状截图捕获到页面00 As-Is中,每个显示结构变化的捕获宽度一个帧。 - 如果
search_design_system找到,使用文件的线框图套件,从skeleton.json在页面01 As-Is Wireframes上构建结构性的现状线框图。 - 交接:要求用户锁定
00 As-Is并保存一个名为baseline R-…的命名版本,然后提供其版本 ID。您无法自行保存版本。 - 将 ID 记录为
version_before。在获得它之前,不得进行进一步的写入。
阶段 6 — 提议
- 将接受的发现分组为决策。每个
D-NNNN.json:标题、发现 ID、上下文、提案、变更描述、实施说明、状态(草稿)。
[后续阶段已截断以进行翻译]