oh-my-openagent 中 designpowers 前端参考语料的物化机制与证据链验证

原创2026-09-20 14:17:071,404 阅读
文章标签:人工智能AI Agent代码智能体多智能体Agent 编排工具调用MCP 服务MCP ClientsAI 技能Agent 记忆GUI 自动化CLI开发工具

oh-my-openagent 中 designpowers 前端参考语料的物化机制与证据链验证

本篇文章基于 oh-my-openagent 仓库中 packages/shared-skills/skills/frontend/references/designpowers/EVIDENCE.md 展开,系统讲解该仓库如何把第三方上游项目 Owl-Listener/designpowers 的参考语料(27 个 skill 与 10 个 agent 角色文件)以「锁定 commit 的 submodule + 构建期物化」的方式注入前端 skill,并通过字节级与归一化比对形成可复现的证据链。读完本文,你将掌握物化管线的完整路径、EVIDENCE 中每一条验证命令的含义与执行方法、被刻意排除的集成面(bridge/canvas/router 类 skill),以及这套语料在 routing、orchestration 与 A/B/C/D 四条 lane 中的实际消费方式。

一、为什么需要「物化证据」:EVIDENCE.md 要回答的问题

designpowers 是一个第三方前端设计领域 skill 集。直接把它当成普通文件拷进仓库存在三个问题:版本不可追溯、内容可能被静默改动、上游桥接类 skill 会与 OpenAgent 既有的前端路由体系打架。因此 oh-my-openagent 采用了「pinned submodule + build/package 期 materialize」策略:

  • 上游源码以 submodule 形式锁定在 packages/shared-skills/upstreams/designpowers,commit 被 pin 到 cb00757da9d554591fa78d27aa1854d60a05c4f7;
  • 构建/打包时,把经过 allowlist 筛选的文件物化到 packages/shared-skills/skills/frontend/references/designpowers/vendor/ 下;
  • EVIDENCE.md 则扮演「证据清单」角色,用一组可粘贴执行的命令,证明物化结果与上游 pinned commit 一致、没有被污染、且被排除项确实不存在。

用一句话概括:EVIDENCE.md 不是设计文档,而是一份可执行、可复现的验收报告,它把「物化是否正确」从一个主观判断变成了机械可核验的事实。

二、物化管线全貌:从 pinned submodule 到 vendor 目录

2.1 上游与本地路径对应关系

根据 packages/shared-skills/skills/frontend/references/designpowers/UPSTREAM.md 中的 manifest,物化的映射关系如下:

上游来源(submodule 内) 物化目标(前端 skill 内)
LICENSE vendor/LICENSE
agents/*.md(allowlist) vendor/agents/
选中 skill 的 skills/*/SKILL.md(allowlist) vendor/skills/*/reference.md

注意第三个映射:上游的 SKILL.md 在物化后统一改名为 reference.md。这不是随意改名,而是刻意的「降级」——物化产物是参考输入,不是可以被独立加载的嵌套 skill 入口点。测试 packages/shared-skills/materialize-frontend-refs.test.ts 对此有直接断言:物化产物中 reference.md 恰好 27 个,而 SKILL.md 必须为 0 个。

物化的 vendor/ 目录本身在 git 中被忽略,只在 npm/package 产物中随前端 skill 一起发布(由前端 skill 的 .npmignore 行为控制)。

2.2 可执行入口在哪

manifest 与物化逻辑分别落在两个脚本中,它们是整条管线的「source of truth」:

也就是说,EVIDENCE.md 中验证的对象,与 packages/shared-skills/skills/frontend/references/designpowers/README.md 中「Third-party files are materialized at build/package time」的描述是同一套东西:manifest 定义选什么,materializer 决定怎么物化,EVIDENCE 负责事后证明结果没跑偏。

三、证据检查集逐条拆解:EVIDENCE.md 的核心内容

EVIDENCE.md 的正文由「Required Checks(必需检查)」与「Byte-for-byte And Normalized Checks(字节级与归一化检查)」两大部分组成,下面逐条还原并说明其意图。

3.1 必需检查(Required Checks)

① 源 commit 锁定

$ git -C packages/shared-skills/upstreams/designpowers rev-parse HEAD
cb00757da9d554591fa78d27aa1854d60a05c4f7

这条命令进入 submodule 目录打印当前 HEAD。它证明整个语料对应的上游版本是固定的——后续所有计数、比对都建立在「就是这个 commit」的前提上。只要 commit 变化,证据链就要整体重跑。

② 物化 skill 目录数 = 27

$ find packages/shared-skills/skills/frontend/references/designpowers/vendor/skills -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' '
27

统计 vendor/skills 下的一级子目录数量。27 正好对应 UPSTREAM.md 中列出的 27 个 included upstream skills(accessible-content、adaptive-interfaces、cognitive-accessibility、design-debate、design-debt-tracker、design-handoff、design-md、design-retrospective、design-review、design-system-alignment、designpowers-critique、heuristic-evaluation、inclusive-personas、inspiration-scouting、interaction-design、motion-choreography、research-planning、responsive-patterns、synthetic-user-testing、taste-feedback、taste-report、token-architecture、ui-composition、usability-testing、verification-before-shipping、voice-and-tone、writing-design-plans)。

③ 物化 reference 文件数 = 27,且不允许出现 SKILL.md

$ find packages/shared-skills/skills/frontend/references/designpowers/vendor/skills -name reference.md | wc -l | tr -d ' '
27
$ find packages/shared-skills/skills/frontend/references/designpowers/vendor/skills -name SKILL.md

第一条确认每个 skill 目录恰好有一份 reference.md;第二条期望输出为空——任何残留的 SKILL.md 都意味着上游嵌套 skill 入口被错误地带入了前端 skill,属于失败状态。

④ 物化 agent 文件数 = 10

$ find packages/shared-skills/skills/frontend/references/designpowers/vendor/agents -maxdepth 1 -type f -name '*.md' | wc -l | tr -d ' '
10

对应 UPSTREAM.md 中列出的 10 个 agent 角色文件:accessibility-reviewer.md、content-writer.md、design-builder.md、design-critic.md、design-lead.md、design-scout.md、design-strategist.md、heuristic-evaluator.md、inspiration-scout.md、motion-designer.md。

⑤ 上游 router / bridge 污染的 skill 必须被排除

$ for s in figma-bridge design-express design-library using-designpowers design-discovery design-memory design-state design-strategy design-taste; do test ! -e packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/$s || exit 1; done
exit=0

这 9 个 skill(figma-bridge、design-express、design-library、using-designpowers、design-discovery、design-memory、design-state、design-strategy、design-taste)是故意不物化的。原因在 README.md 与 UPSTREAM.md 中写得很清楚:它们是 bridge/state/router 集成面,会与 OpenAgent 既有的前端工作流形成竞争。尤其 using-designpowers 是上游的「路由入口」skill,一旦混入,等于引入了第二套编排体系。循环中任一目录存在即 exit 1,整条验证失败。

⑥ 禁止的集成目录必须缺席

$ find packages/shared-skills/skills/frontend/references/designpowers/vendor -path '*/hooks/*' -o -path '*/scripts/*' -o -path '*/.claude/*' -o -path '*/.gemini/*' -o -path '*/.github/*'

输出必须为空。它验证物化产物里没有 hooks、scripts、.claude、.gemini、.github 等「可执行/可自动化」的目录结构——designpowers 语料在 OpenAgent 里是纯声明式的参考输入,不允许携带任何运行时代码面。

3.2 字节级与归一化检查(Byte-for-byte And Normalized Checks)

① LICENSE 字节级一致

$ cmp -s packages/shared-skills/upstreams/designpowers/LICENSE packages/shared-skills/skills/frontend/references/designpowers/vendor/LICENSE
exit=0

cmp -s 做逐字节比较,零输出 + exit=0 表示两个 LICENSE 完全相同,许可证随包发布时没有任何篡改。

② 10 个 agent 文件逐字节一致

$ for file in packages/shared-skills/upstreams/designpowers/agents/*.md; do cmp -s "$file" "packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/${file##*/}"; done
exit=0

对 agents/*.md 逐一执行 cmp -s,要求上游与物化产物完全一致——agent 文件不经过任何转换,直接复制。

③ 27 个 skill 的归一化比对(最关键的检查)

$ node --input-type=module <<'NODE'
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { includedDesignpowersSkills } from "./packages/shared-skills/scripts/designpowers-refs-manifest.mjs";
import { normalizeSkillFrontmatter } from "./packages/shared-skills/scripts/materialize-frontend-refs.mjs";
const rawMismatches = [];
const normalizedMismatches = [];
for (const name of includedDesignpowersSkills) {
  const upstream = readFileSync(join("packages/shared-skills/upstreams/designpowers/skills", name, "SKILL.md"), "utf8");
  const materialized = readFileSync(join("packages/shared-skills/skills/frontend/references/designpowers/vendor/skills", name, "reference.md"), "utf8");
  if (upstream !== materialized) rawMismatches.push(name);
  if (normalizeSkillFrontmatter(upstream) !== materialized) normalizedMismatches.push(name);
}
console.log(`raw_skill_cmp_mismatches=${rawMismatches.length}`);
console.log(`normalized_skill_cmp_mismatches=${normalizedMismatches.length}`);
if (normalizedMismatches.length > 0) throw new Error(`normalized mismatches: ${normalizedMismatches.join(", ")}`);
NODE
raw_skill_cmp_mismatches=27
normalized_skill_cmp_mismatches=0
exit=0

这段脚本通过 Node 的标准库读取上游 SKILL.md 与物化 reference.md,然后做两轮比较:

  • raw 比较:上游文本直接与物化文本逐字符比较,结果为 raw_skill_cmp_mismatches=27——27 个文件全部不同;
  • normalized 比较:把上游文本先经 normalizeSkillFrontmatter()(来自 materialize-frontend-refs.mjs)归一化后再比,结果为 normalized_skill_cmp_mismatches=0。

EVIDENCE.md 对此给出了明确解释:这 27 处 raw mismatch 全部是物化器对 frontmatter 中 description: 字段做的预期引号规范化改动,而 normalized 检查为 0 则证明——剥离该改动后,随包发布的 skill 正文与上游零漂移。换句话说:物化器只动 frontmatter 元数据,不碰任何正文内容。若 normalized mismatch 大于 0,脚本会直接 throw 让验证失败。

④ 被排除 router 的硬调用不得残留

$ for f in packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/*/reference.md; do if rg -q 'MUST invoke the `using-designpowers` skill FIRST|invoke the `using-designpowers` skill FIRST' "$f"; then echo "$f"; exit 1; fi; done
exit=0

用 rg -q 在所有物化 reference.md 中搜索「必须首先调用 using-designpowers skill」这类硬指令。即使 using-designpowers 这个 skill 目录被排除了,它的调用指令文本若残留在其他 skill 正文里,同样会污染路由——所以这条检查连「文本级污染」也一并堵死。

四、物化结果如何被消费:前端参考路由与四条 lane

EVIDENCE.md 证明的是「语料正确落地」,而 packages/shared-skills/skills/frontend/references/designpowers/README.md 定义了这批语料为什么存在、何时加载、谁拥有什么。二者合起来才构成完整闭环。

4.1 定位与加载顺序

designpowers 前端参考是一个内部前端规则集(internal frontend ruleset),不是独立 skill。/frontend 仍是 Web UI、UX、视觉设计、无障碍、设计 QA 与前端实现路由的唯一公开激活点。它被要求:每当创建或更新 DESIGN.md 的实现/重设计任务、以及需要设计操作层指导(personas、认知无障碍、critique、design debt、handoff、合成用户测试、动效指导、designpowers 式角色参考)时加载。

规定的加载顺序为:README.md(集成契约)→ routing.md(上下文如何喂给既有路由)→ orchestration.md(共享状态与 Direct/Auto 语义)→ lane 文档(lane-c-review.md 每次评审都加载,其余 lane 按阶段加载)。同时明确所有权边界:references/design/README.md 仍拥有 DESIGN.md 契约与品味路由,references/perfection/README.md 仍拥有 Lighthouse/性能/SEO/无障碍审计,/visual-qa 仍拥有渲染证据,/ulw-plan、/ulw-execute、/review-work 仍拥有各自阶段的所有权。

4.2 四条 lane 与 27 个 skill 的映射

物化的 27 个 skill 并非平铺直叙地「可用」,而是按阶段映射到四条 lane:

  • Lane A(Direction & Discovery):喂给 ulw-plan。把 research-planning、inclusive-personas、design-debate、inspiration-scouting 等转成规划输入;上游被排除的 design-discovery、design-strategy、design-taste、design-state 的概念被以「authored concept」形式保留(如品味校准仅针对当前项目、状态账本固定用 .omo/frontend-design/state.md),但绝不引入第二套规划器。
  • Lane B(Design Execution):喂给 ulw-execute worker,UI 实现始终走 frontend。把 ui-composition、interaction-design、motion-choreography、responsive-patterns、adaptive-interfaces、cognitive-accessibility、accessible-content、voice-and-tone、token-architecture、design-system-alignment 转成 worker 的验收标准(如每个交互组件必须定义 default/hover/focus/active/disabled/loading/success/error 状态、要求 200% 缩放下响应式证明等)。
  • Lane C(Review & Repair):先跑 visual-qa 拿客观渲染证据,再用 designpowers-critique、heuristic-evaluation(Nielsen H1-H10)、synthetic-user-testing、usability-testing、verification-before-shipping 做设计判断,最后交给 review-work。明确禁止在证据缺失时先做判断。
  • Lane D(Memory, Debt & Handoff):用 design-debt-tracker、design-handoff、design-retrospective、taste-report 维护 .omo/frontend-design/state.md 状态账本、债务登记、交接与复盘。关键原则是「设计记忆是镜子不是方向盘」——观测性记忆只做描述性记录,不得反向成为未来项目的约束。

4.3 编排契约中的关键约束

packages/shared-skills/skills/frontend/references/designpowers/orchestration.md 补充了与物化证据呼应的约束:整个参考声明式(declarative),不引入运行时代码、hooks、脚本、bridge、scheduler 或可调用 API。Direct/Auto 只是 prompt 语义(Direct 走已知路由、Auto 可为低风险细节选默认值),两者都不得创建后台自动化。当设计结论冲突时按「安全与无障碍 → 用户目标与主任务 → 包容性 persona 通过标准 → 项目设计系统 → 品味方向 → 可逆偏好」的调和阶梯(Reconciliation Ladder)解决,高层要求无法同时满足时暂停征询用户。

designpowers 的 10 个 agent 文件(如 design-critic、accessibility-reviewer、heuristic-evaluator)在 OpenAgent 语境中只是角色参考——用于措辞「act as a design critic」这类 prompt,不是已安装的 agent、不可选的 agent 类型,也没有独立运行时。这与物化证据中「agent 文件逐字节复制、不含可执行结构」的检查完全一致。

五、测试层的持续保障

物化正确性不仅在 EVIDENCE.md 里靠一次性命令保证,还固化在自动化测试 packages/shared-skills/materialize-frontend-refs.test.ts 中。与本文主题直接相关的断言包括:

  • 所有 manifest 目标在 submodule 存在时必然落在磁盘上(L16-L23);
  • designpowers 语料完整物化(L36-L41);
  • 物化 skill 的 frontmatter 必须是 YAML 安全的,且 name/description 元数据齐全(L43-L59);
  • reference.md 恰好 27 个、SKILL.md 必须为 0(L61-L71)——把「物化成参考而非嵌套入口」这一约束固化为持续集成断言。

也就是说:EVIDENCE.md 是人工可执行的验收单,materialize-frontend-refs.test.ts 是每次 CI 自动复跑的验收单,两者验证的是同一组事实。

六、验证实操:如何亲手复跑证据链

如果你 clone 了本仓库并初始化了 submodule,可以按以下顺序复现 EVIDENCE.md 的全部结论:

  1. 确认上游 commit:git -C packages/shared-skills/upstreams/designpowers rev-parse HEAD,期望 cb00757da9d554591fa78d27aa1854d60a05c4f7;
  2. 确认 27 个 skill 目录、27 个 reference.md、0 个 SKILL.md、10 个 agent 文件;
  3. 确认 9 个被排除 skill 目录不存在、vendor/ 下无 hooks/scripts/.claude/.gemini/.github 结构;
  4. 执行 LICENSE 与 agent 文件的 cmp -s 循环;
  5. 运行第二节中的 Node 归一化比对脚本,期望 raw_skill_cmp_mismatches=27、normalized_skill_cmp_mismatches=0;
  6. 执行 rg 扫描,确认无 using-designpowers 硬调用残留。

六步全绿,即证明当前 checkout 的 designpowers 参考语料与 pinned upstream 一致、内容零正文漂移、无 router/bridge 污染、无运行时代码面——也就是 EVIDENCE.md 这份文档存在的全部意义。

七、总结

oh-my-openagent 对 designpowers 的处理是一个「第三方语料安全集成」的完整样板:pinned submodule 保证来源可追溯,manifest + materializer 保证选择与转换可控,EVIDENCE.md 保证结果可证明,自动化测试保证结论可长期维持,而 routing / orchestration / 四条 lane 保证物化产物只以参考输入的姿态被消费。理解这条证据链,你就同时掌握了这套仓库中「如何安全地把别人的 skill 体系并入自己的路由体系」的核心方法论。

登录后查看全文
oh-my-openagent