首页
/ Impeccable 的降级 Documenter 子代理:从已交付产物中记录设计系统的完整机制与契约

Impeccable 的降级 Documenter 子代理:从已交付产物中记录设计系统的完整机制与契约

2026-09-05 15:45:40作者:尤峻淳Whitney

本文解析 Impeccable 技能包中的降级模式文档角色参考文件 .agent/skills/impeccable/reference/degraded/documenter.md。该文件是构建期自动生成的"无子代理回退"指令集,用于在没有 subagent 能力的 harness 上以内联方式执行"构建完成后从实际交付产物记录 DESIGN.md"这一角色。读完后你将理解 Impeccable 的降级文件生成管线(单一来源 skill/agents/、构建期前缀注入)、Documenter 角色的输入/输出契约、五步工作流的完整规则,以及它与设计系统记录规范 reference/document.md 之间的调用关系。

什么是 degraded/documenter.md:无子代理环境的内联回退角色

该文件首行即声明了自己的来源:

<!-- Generated from skill/agents/ at build time. Do not edit; edit the agent definition. -->

紧随其后的构建期注入前缀(preamble)是这个角色在降级运行时必须遵守的第一条元规则:

This harness has no subagent capability, so you are running this role inline. Step fully out of the work you just finished, adopt only this file's instructions for the pass, and disclose the substitution in one line when you report. Where the text below addresses a parent agent, you are both parties: produce the full output contract first, then act on it yourself.

这段前缀规定了降级运行的三条纪律:

  • 角色切换:执行者必须完全退出刚完成的工作上下文,只采纳本文件的指令,避免"边改边记"导致记录者带着实现者的偏见。
  • 降级披露:汇报结果时必须用一行声明"本次为内联降级运行"。这与 critique.md 中"静默的降级运行等于失败的运行"(silent degraded run is a failed run)的横幅规则同属一套披露原则。
  • 自产自消:当正文中"父代理(parent agent)"出现时,同一上下文身兼两方——先产出完整的输出契约(output contract),再自己执行它。

这个 preamble 并非手写,而是由构建脚本统一注入。在 scripts/lib/transformers/factory.js 中,DEGRADED_PREAMBLE 常量以逐字匹配的方式定义了这段文本:

// Preamble prepended to every generated degraded-mode fallback reference file.
// These files are single-sourced from skill/agents/ so a harness with no
// subagent capability runs each role inline from the same specialized text.
const DEGRADED_PREAMBLE = `<!-- Generated from skill/agents/ at build time. Do not edit; edit the agent definition. -->
This harness has no subagent capability, so you are running this role inline. ...`;

注释明确了两点工程决策:这些文件单一来源(single-sourced)自 skill/agents/,即 skill/agents/impeccable-documenter.md 才是角色定义的权威版本;降级文件与原生子代理文件走同一条渲染管线,因此 <codex> provider 块与 {{placeholder}} 占位符在两种产物中解析结果完全一致。

构建管线如何生成 degraded 文件

scripts/lib/transformers/factory.jstransform 函数在遍历每个 skill 时,若该 skill 声明了 agents 数组,则为每个 agent 生成一个降级参考文件:

// Generate degraded-mode fallback reference files from the shipped
// subagent definitions. Single-sourced from skill/agents/ so a harness
// with no subagent capability runs each role inline from the same
// specialized text. Role name = agent name minus the `impeccable-`
// prefix.
if (skill.agents && skill.agents.length > 0) {
  const degradedDir = path.join(skillDir, 'reference', 'degraded');
  ensureDir(degradedDir);
  for (const agent of skill.agents) {
    const role = agent.name.replace(/^impeccable-/, '');
    const body = renderAgentBody(agent, { providerTags, placeholderKey, allSkillNames, scriptsPath });
    const content = `${DEGRADED_PREAMBLE}\n\n${body.replace(/^\s+/, '')}`;
    writeFile(path.join(degradedDir, `${role}.md`), content);
    refCount++;
  }
}

其中可以确认的实现事实:

  • 文件名 = 去掉 impeccable- 前缀的角色名impeccable-documenterdegraded/documenter.md。同理生成 asset-producer.mdfinish-reviewer.mdmanual-edit-applier.md 等四个降级角色文件。
  • 正文统一经过 renderAgentBodyfactory.js):先编译 provider 块、再替换占位符、剥离规则标记、替换 {{scripts_path}},保证降级文件与 Codex .toml、原生 agent 文件三种表面的正文解析行为一致。
  • 分发范围:从 scripts/lib/transformers/providers.js 的注释可见,degraded 回退主要服务于 Copilot 等模型无法自动发现子代理的表面,因此即使这些 harness 不加载原生 agent,降级文件也会随 skill 一起分发。

角色定义:agent frontmatter 中的运行参数

降级文件正文的权威来源是 skill/agents/impeccable-documenter.md,其 YAML frontmatter 给出了角色的运行参数:

name: impeccable-documenter
codex-name: impeccable_documenter
description: Records DESIGN.md and its sidecar from a finished Impeccable build,
  deriving the design system from the shipped artifact rather than from intentions.
tools: Read, Write, Bash, Glob, Grep
model: inherit
effort: medium
max-turns: 30
nickname-candidates:
  - System Scribe
  - Token Surveyor
  - Ground Truth

这些参数直接塑造了正文的行为约束:

  • max-turns: 30 对应正文中的"hard turn ceiling"(硬轮次上限)。正文将这一限制转化为明确的行为策略:"a run that ends before DESIGN.md is written has recorded nothing"——上限耗尽前没写出文件等于什么都没记录。因此要求把多个 Read 批进同一轮、优先读取 reference/document.md 和样式表、对组件做采样而非遍历整棵树、并在运行到中段就开始动笔。
  • tools: Read, Write, Bash, Glob, Grep 声明了最小工具集:能读、能搜、能写,与"从已交付代码取证"的职责匹配。
  • nickname-candidates 中的 "Ground Truth" 点出了整个角色的哲学:交付物才是事实来源。

核心哲学:ground truth 是已交付的产物

正文第一段确立了 Documenter 的立身之本:

You record a project's design system after the build is done. Ground truth is the shipped artifact: every token and rule you write must be evidenced by the built code, never by what was planned. Writing the system after the fact is the point; a rulebook written before the build gets defended against reality instead of describing it.

两个关键论断:

  1. 事后记录(write after the fact)是刻意设计,不是流程妥协。规则手册若先于构建写成,构建者会"对着现实为它辩护",文档与实现逐渐脱节;反之从已交付代码反推,每条规则天然有据可查。
  2. 每条 token 与规则必须能被构建代码证据支撑,永远不能来自计划(intention)。这与 SKILL.src.md 中"Visual authority is evidence, not a filename"的原则一脉相承。

输入契约(Input Contract)

文件以 "Expect:" 开头声明调用方必须提供的一切输入:

  • 项目根路径(project root);
  • 产物路径(the artifact path(s))——待记录的已构建界面;
  • 方向契约文本(the direction contract text):THESISOWN-WORLDSTORYFIRST VIEWPORTFORM 五个块;
  • PRODUCT.md 路径
  • reference/document.md 的路径——DESIGN.md 的操作规范(operating spec);
  • 写入边界(the boundary to write at):项目根还是 app 根,决定 DESIGN.md 落在哪一层。

其中一条增量语义特别重要:

An existing DESIGN.md path means update, not replace: preserve confirmed incumbent decisions and reconcile them with the build.

即已存在的 DESIGN.md 触发的是更新而非替换:保留已确认的既有决策,并让它与本次构建对齐。这防止文档者每次构建都把设计系统从零重推一遍,破坏文档的连续性。

五步工作流(Workflow)

文件主体是编号五步的工作流,每一步都是可独立引用的操作规则:

第 1 步:通读操作规范

Read reference/document.md in full; it is the operating spec for DESIGN.md's format, token schema, sidecar, and section order. Follow it exactly.

即完整读取 skill/reference/document.md(在 .agent 表面即 .agent/skills/impeccable/reference/document.md)。该文件规定了 DESIGN.md 的 frontmatter token schema、.impeccable/design.json sidecar 的 schemaVersion 2 结构与八个正典章节顺序。Documenter 的产物格式完全由它约束,"Follow it exactly" 不允许自由发挥。

第 2 步:扫描交付物取证

Scan the artifact: stylesheets, custom properties, computed values in the source, component patterns, spacing rhythm, type ramp as actually used.

取证对象包括:样式表、CSS 自定义属性(custom properties)、源码中的计算值、组件模式、间距节奏(spacing rhythm)、以及实际使用的字号阶梯(type ramp as actually used)。同时引入方向契约与构建结果的冲突裁决规则:

The direction contract's OWN-WORLD block names the world; the build shows how it landed. Where they diverge, the build wins and the prose may note the divergence.

方向契约(OWN-WORLD 块)命名了"目标世界",而构建展示了它实际落地的样子。冲突时构建胜出,正文可以注明分歧——这与"ground truth 是交付物"的哲学完全一致。

第 3 步:只写入持久的系统规则

Write DESIGN.md (and the sidecar per the spec) with only durable system rules: tokens the project actually uses, named rules the build actually follows. Skip one-off values; a token used once is not a system.

写入的门槛是"持久性":只记录项目实际在用的 token 与构建实际遵循的命名规则,跳过一次性取值——只被使用一次的 token 不构成系统。这条规则与 document.md Pitfalls 一节"Don't extract every token. Stop at what's actually reused; one-offs pollute the system." 互为呼应。

第 4 步:两种已被现场观察到的规则记录错误

Two ways a recorded rule goes wrong, both observed live: a prohibition that bans a device the world itself uses natively, and a value recorded to legitimize a defect.

文档者必须规避两类经真实会话(observed live)观察到的错误:

  1. 禁止条款禁掉了世界自身原生生成的手法(a prohibition that bans a device the world itself uses natively)——因此每条禁令都要对照世界自己的素材(the world's own materials)校验。
  2. 记录某个值只是为了"合法化"一个缺陷(a value recorded to legitimize a defect)——值的存在必须由构建与可读性(legibility)赢得位置,而不是为了让检测器的某条 finding 消失。

第 5 步:绝不把 craft-floor 拒收项正典化为系统规则

Never canonize a craft-floor refusal into the system: an element the floor bans (kickers and eyebrows, hard offset shadows outside a neobrutalist world, glyph icons, system display faces) is recorded in your not-canonized line as a defect the build carries, never as a design-system rule for future surfaces to inherit.

craft-floor(品质地板,见 skill/reference/craft-floor.md)的拒收项——标题上方的 kicker/eyebrow 小字、非新粗野主义世界里的硬偏移阴影、glyph 图标、系统显示字体——即使出现在构建产物中,也只能记入"未正典化"(not-canonized)行,作为构建携带的缺陷,绝不能成为未来表面要继承的设计系统规则。文件给出了一段真实的事故警示:

A live session shipped five invented kickers and the documenter wrote their style into DESIGN.md; that is how one violation becomes the house style.

一次真实会话交付了五个杜撰的 kicker,文档者把它们的样式写进了 DESIGN.md——一次违规就这样变成了"house style"。这条规则解释了为什么输出契约里强制要求一行"未正典化声明":没有这行披露,缺陷就会在下一轮生成中被当作系统规则继承。

输出契约(Output Contract)

Return: the file paths written, a five-line summary of the recorded system (palette strategy, type ramp shape, named rules), and one line naming anything in the build you deliberately did not canonized and why. No other prose.

产出被严格限定为三部分,除此之外禁止任何其他散文

  1. 已写入的文件路径(DESIGN.md 与 sidecar);
  2. 五行摘要:配色策略(palette strategy)、字号阶梯形态(type ramp shape)、命名规则(named rules);
  3. 一行未正典化声明:点名构建中刻意未正典化的内容及其原因。

配合 max-turns: 30 的上限与"中段必须开始写作"的策略,整个契约呈现出一种工程化的时间盒设计:宁可用一手证据(primary evidence)写出一份不完美的系统记录,也不要做一个永远落不了盘的穷尽式扫描。

在整体流程中的位置:new-work 的收尾环节

skill/reference/new-work.md 可以看到 Documenter 被调度的时机与方式:

Then spawn the shipped documenter, impeccable-documenter (impeccable_documenter in codex), with the project root, the artifact path, the direction contract, PRODUCT.md, the document.md reference path, and the boundary to write at; it records DESIGN.md and the sidecar from the built world, ground truth over intention; without subagents the pass runs from degraded/documenter.md.

三个要点:

  • 调用参数与输入契约一一对应(项目根、产物路径、方向契约、PRODUCT.md、document.md 参考路径、写入边界)。
  • 原生路径派生 impeccable-documenter(Codex 侧为 impeccable_documenter);无 subagent 时从 degraded/documenter.md 内联执行——这正是本文档文件的消费场景。
  • 文档者跑在最后一轮修正落地之后(the documenter runs after the last correction lands)。若文档之后还有修复轮次,必须在被改动的表面重跑 documenter,因为"一份描述已不存在的布局的 DESIGN.md,会把缺陷变成系统指引"(turns defects into system guidance)。

此外 SKILL.src.md 的 Commands 表将 document 命令(Generate DESIGN.md from existing project code)指向 reference/document.md。也就是说:/impeccable document 是用户显式命令路径,degraded/documenter.md 则是 new-work 自动收尾路径在无子代理 harness 上的内联降级路径,二者共享同一份操作规范。

操作规范纵深:DESIGN.md 格式与 sidecar(document.md 摘要)

Documenter 的"输出格式法典"是 skill/reference/document.md。为让本文可独立成立,这里摘要其关键约束(完整规则以该文件为准):

frontmatter token schema(机器可读层)

---
name: <project title>
description: <one-line tagline>
colors:
  primary: "#b8422e"
  neutral-bg: "#faf7f2"
typography:
  display:
    fontFamily: "Cormorant Garamond, Georgia, serif"
    fontSize: "clamp(2.5rem, 7vw, 4.5rem)"
    fontWeight: 300
    lineHeight: 1
    letterSpacing: "normal"
rounded:
  sm: "4px"
  md: "8px"
spacing:
  sm: "8px"
  md: "16px"
components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.neutral-bg}"
    rounded: "{rounded.sm}"
    padding: "16px 48px"
---

关键规则(document.md 原文逐字约束):

  • Token 引用使用 {path.to.token};组件可引用原语,原语之间不得互相引用;
  • 颜色接受任意合法 CSS 颜色字符串,hex 是可移植性默认值,但项目规范来源是 oklch() 等格式时必须原样保留;
  • 组件子 token 仅限 8 个属性backgroundColortextColortypographyroundedpaddingsizeheightwidth;阴影、动效、focus ring 等放进 sidecar;
  • scale key 开放:沿用项目自己的命名,不要改名成 Material 默认值;
  • frontmatter 是规范性的(normative):不要在正文里用不同取值重复断言同一 token。

八个正典章节(固定顺序,可省略不相关章节,但不得改名)

  1. ## Overview
  2. ## Colors
  3. ## Typography
  4. ## Layout
  5. ## Elevation & Depth
  6. ## Shapes
  7. ## Components
  8. ## Do's and Don'ts

sidecar:.impeccable/design.json(schemaVersion 2) 承载 frontmatter 装不下的扩展:每色 8 步 tonalRamp、阴影/动效/breakpoint token、可注入 shadow DOM 渲染的完整组件 HTML/CSS(类名须带 ds- 前缀、图标内联 SVG、Tailwind 工具类必须展开为字面量 CSS),以及叙述层(northStar、rules、dos/donts,从 DESIGN.md 逐字抽取不得改写)。sidecar 是 frontmatter 的扩展而非重复,随 DESIGN.md 一起再生。

两种运行模式:Scan mode(有可分析的代码,自动抽取后向用户确认描述性语言)与 Seed mode(无实现,经由 new-work 工作坊写方向性种子文件,并以 <!-- SEED: ... --> 标记承诺"有代码后重跑 /impeccable document")。Documenter 角色执行的正是 Scan mode 的自动化收尾变体——它从已交付构建中抽取,而非与用户逐轮问答。

如何查看与验证这些文件

小结

degraded/documenter.md 是 Impeccable "设计系统记录"能力的无子代理回退面:它由构建管线从 skill/agents/impeccable-documenter.md 单一来源生成,注入固定 preamble 后与原生子代理走完全相同的正文渲染管线。该角色的价值不在格式模板,而在三条纪律——ground truth 取自已交付产物而非意图冲突时构建胜出拒收项绝不正典化为 house style——以及一份严格限定的输出契约(路径 + 五行摘要 + 一行未正典化声明)。理解这套"事后取证式文档化"机制,是理解 Impeccable 如何让 AI 生成的新界面持续保持 on-brand 的关键一环。

登录后查看全文
热门项目推荐
相关项目推荐