首页
/ Impeccable Doctor 运维指南:如何检查与修复 DESIGN.md、config.json 等设计制品漂移

Impeccable Doctor 运维指南:如何检查与修复 DESIGN.md、config.json 等设计制品漂移

2026-09-08 11:22:08作者:凤尚柏Louis

Impeccable 是一套让 AI 设计工具链更可靠的设计语言与技能体系,而 doctor/impeccable doctor)是其中专门负责"维护"而非"设计"的巡检命令:它报告并修复项目里的 Impeccable 制品与该技能安装版本实际读取规则之间产生的漂移。本文以 .trae/skills/impeccable/reference/doctor.md 为骨架,结合仓库中的技能路由与配置文档,完整讲解漂移的类型划分、诊断命令的用法、findings 数据结构、按严重度分级处理的原则、monorepo 场景的专项巡检,以及如何关闭会话启动时的廉价巡检,让读者既能独立跑通一次 doctor 检查,也能理解每一项 finding 背后的设计意图。

doctor 的职责边界:它维护什么,又不做什么

doctor 报告与修复的漂移对象是项目中以下 Impeccable 制品与"当前安装版本实际读取方式"之间的不一致:

  • PRODUCT.md
  • DESIGN.md 及其 .impeccable/design.json sidecar 文件;
  • .impeccable/config.json(以及按开发者覆盖的 .impeccable/config.local.json);
  • 持久化的 surface briefs(表层设计简报);
  • design hook(设计钩子的安装与配置状态)。

这是一次纯粹的维护动作,不是设计动作:不要重新设计任何东西,不要打开报告点名的文件之外的任何文件,也不要顺带运行其他任何命令。在技能路由层面,skill/SKILL.src.md 中同样明确了一条规则——"永远不要把漂移修复当作设计任务的副作用":CONTEXT_STALE finding 只在用户要求时才被处理,唯一例外是标记为 auto 的 finding,它会在该文件下一次被写入时自动执行。

三种漂移要分清:版本、Schema 与"真相"

文档把口语中统称的"过时"(out of date)拆成三种性质截然不同的漂移,处理方式完全不同:

  • 工具版本漂移(Tool version):安装的技能比已发布版本旧。context.mjs 在启动时用 UPDATE_AVAILABLE 报告这一情况,npx impeccable update 可以修复它。这不是 doctor 命令的职责。
  • Schema 漂移(Schema drift):某个制品是由旧版 Impeccable 写出的——存在没有读取方字段、现在才被期望的字段、位于废弃位置的旧文件。这类漂移是机械性的,doctor 命令能修复其中大部分。
  • 真相漂移(Truth drift):代码演进之后,文档不再能描述现状。没有任何文件比对能判定这一点——document 技能拥有 DESIGN.mdinit 技能拥有 PRODUCT.md,doctor 的职责是把一个具体的缺口交给它们,而不是转交一个模糊的怀疑。

这条分类决定了后续所有动作的原则,尤其是"不要过度断言真相漂移"(见后文)。

Step 1:运行一次巡检

诊断入口是 doctor 脚本,命令路径以具体安装布局为准(本技能在 .trae 环境下的标准写法):

node .trae/skills/impeccable/scripts/doctor.mjs --json

指定目标:--target <path>

当用户在 monorepo 中指定了某个 workspace、文件或路由时,加上 --target <path>

node .trae/skills/impeccable/scripts/doctor.mjs --json --target <path>

不带 --target 时,报告描述的是仓库根目录;而在 monorepo 里,根目录往往不是正确的项目,因此这一步的判断很重要。

理解输出结构

--json 输出携带:

  • findings:每个 finding 是一个结构化对象 { id, artifact, path, severity, summary, fix },其中 id 是 finding 标识、artifact 指涉的制品、path 相关路径、severity 严重度(决定"应该发生什么")、summary 摘要、fix 建议的修复方式;
  • 在 monorepo 中还会携带 workspaces:每个 app 的 product 与 design 解析结果。

如果输出里出现 ruleRegistryAvailable: false,意味着被忽略的 rule id 无法校验(规则注册表不可用);应当如实告知用户"该忽略列表未能验证",而不要暗示该列表是干净可信的。

好的结果是什么

一个空的 findings 数组就是最好的结果。这时用一行说明"没有发现漂移"即可停止,不要为了找事而扩大动作。值得注意的是:findings 不是错误,doctor 命令不会因为存在 findings 而失败——这正是"严重度只表达应该做什么"的体现。

Step 2:按严重度分级行动

severity 表达的是"接下来应该发生什么",而不是"问题有多糟糕"。三种严重度对应三类不同的处理动作:

auto:无需决策,直接修复

auto 不携带任何决策。运行一次修复命令即可:

node .trae/skills/impeccable/scripts/doctor.mjs --fix

该命令只应用所有 auto finding(且仅限不涉及任何判断的场景),完成后用一行汇报它移动/修改了什么。修复前不需要先征求许可,修复后也不需要再追问这些项——doctor --fix 只动 auto 级且无判断参与的项,这是它在 CLAUDE.md 中被界定为"自动修复在下一次对该文件写入时发生"的实现细节。

mention:只需告知,暂不决策

mention 需要用户知晓,但不需要用户现在做出任何决定。用一句话陈述每一条 mention,并附带它给出的修复建议即可。

route:指向某个具体命令

route 需要一个特定的命令来收口:说出命令名以及它能弥合的缺口。是否执行取决于用户:initdocument对话式的过程,不是可以无人值守替你执行的修复,因此只有当用户在本轮明确要求时才去运行。

三种分组要在一次巡检报告里全部汇报。报告不是错误清单,doctor 命令不会因 findings 的存在而失败。

Step 3:废弃字段具有约束力

当一个 finding 报告了废弃字段(当前例子是 ## Register)时,它不是一条风格建议。从这一刻起,所有决策都应把该字段当作不存在来处理——无论它现在存着什么样的值——并向用户提供删除该小节的建议。

文档给出的理由非常尖锐:保留它"以防万一",正是让一条已被退役的决策轴继续操控当前输出的方式。换言之,schema 漂移的修复不只是"清理旧数据",更是切断旧版本规则对当前行为残留影响的机制性手段。

Step 4:不要对真相漂移过度断言

doctor 刻意把两类 finding 的处理边界写死,防止把"数据信号"误读成"文档有错"。

design-md-drift:提交数不等于矛盾

design-md-drift 统计的是"自 DESIGN.md 上次被编辑以来,视觉源码目录产生的提交次数"。一个提交计数并不是文档与现状矛盾的证据。正确的做法是:

  1. 报告这个数字;
  2. 说明它衡量的是什么;
  3. 如果用户想知道文档是否真的错了,就直接拿当前 tokens 与 components 去通读 DESIGN.md,并基于阅读结果回答;
  4. 永远不要因为数字大就断言 DESIGN.md 已经过时。

workspace-context-inherited:继承是设计行为

同样的克制适用于 workspace-context-inherited。继承(一个 workspace 沿用根或父级的产品记录)是刻意设计的行为,不是缺陷。某一份 product 记录是否如实地描述多个 app,这是一个该由用户回答的问题,而不是一个需要 doctor 去"修复"的 bug。

Monorepo 专项发现(Monorepo notes)

在 monorepo 布局下,doctor 的输出会多出若干专项 finding,并附 workspaces 表,展示哪些 app 自带上下文、哪些继承上下文、哪些完全没有上下文。在提出任何修改建议之前,先用这张表让用户看清楚现状。

workspace-platform-native-evidence:最重要的 monorepo finding

这是 monorepo 场景里"最重要"的一条:当一个 workspace 携带原生构建文件、却继承了解析结果为 web 的根记录时,它整个生命周期都会收到 web 方向的指导,永远加载不到 ios.mdandroid.md 这两份平台参考。

修复方式是给该 workspace 添加一份子级 PRODUCT.md——因为一份被继承的记录无法同时承载两个平台。这就是"继承"在平台维度上的天然上限。

config-project-roots-match-nothing:projectRoots 全部落空

该 finding 意味着 .impeccable/config.json 中配置的每一个 projectRoots glob 都没有命中任何目录,于是仓库根目录静默地顶替成为了活跃项目。最常见的诱因是 workspace 目录被重命名。处理方式:把匹配模式(patterns)报告给用户,并询问这些模式本应指向哪些目录。

config-invalid-build-path / config-build-path-unset:同一个 buildPath 键的两面

这两条 finding 都围绕 .impeccable/config.json 中的同一个键:buildPath(在 gitignored 的 .impeccable/config.local.json 中也可以设置,且 local 文件对该开发者优先)。它只取 compcode 两个值,决定新 surface 是从生成的 comp 构建(comp-first)还是直接在代码中构建(code-first):

{ "buildPath": "comp" }
  • config-invalid-build-path:存在一个无法被读取的值(不是 comp 也不是 code)。需要特别指出:一个不可读的值不会回退到另一条路径——所以一个本意是 code 的项目,可能一直在按 comp-led 的方式构建。报告时要给出该值的确切内容。
  • config-build-path-unset:该 finding 只在"项目做过方向性工作却从未记录偏好"时触发;只有当你的工具面(tool surface)具备图像生成能力时,它给出的"设置该值"的提议才成立。没有图像生成能力就没有可选的余地,也就没有需要说的话。

关于 buildPath 的语义,可在 README.md 中找到更完整的背景:comp-first 组合性更强但耗时更长,code-first 更精简更快;/impeccable init 会在初始化时询问一次并把答案写入 .impeccable/config.jsonconfig.local.json 的覆盖机制专门服务于"你的 harness 没有图像生成能力"的机器场景;在 monorepo 中通常在根提交一份共享值,需要不同行为的 workspace 再各自设置。

关闭启动巡检:让报告只在被要求时出现

context.mjs 会在每次会话开始时报告这些 finding 的廉价子集,并按"每项目每周至多一次"的节奏节流。两条静默途径:

  • 配置级:在 .impeccable/config.json 中设置 "stalenessCheck": false
  • 单会话级:设置环境变量 IMPECCABLE_NO_STALENESS_CHECK=1

注意:关闭启动巡检不会禁用 doctor 命令本身。对"只希望在用户主动询问时才拿到报告"的用户来说,"关闭 boot check + 保留 doctor 命令"正是应当推荐的组合。这一机制与 skill/SKILL.src.md 中的 CONTEXT_STALE 指令对应——Setup 输出中的 CONTEXT_STALE 就是同一份报告的子集,应按照该指令自身的说明就地处理,而不是擅自运行完整的 doctor。

为什么 doctor 独立于设计命令体系

从技能路由结构看,doctor 是有意与设计命令体系隔离的。在 skill/SKILL.src.md 中,doctor 遵循 hookspin 的"一行路由 + 独立 reference 文档"模式,而不在 IMPECCABLE_SUB_COMMANDScommand-metadata.jsonSKILL_CATEGORIES 或命令白名单中,也不计入设计的 23 条命令总数——维护性工具被刻意排除在设计菜单之外。当用户调用 /impeccable doctor,或提出"什么东西过时了 / 需要刷新"之类的问题时,才加载 reference/doctor.md(源码级同文镜像见 doctor.md)。

这一隔离的意义在于:巡检是低频维护,设计是高频创作。让维护工具混入设计命令,会让它在不相干的上下文中被误触发;而让漂移问题以 CONTEXT_STALE 这样的廉价信号出现在会话开头、以 doctor 全量巡检出现在用户明确要求时,才是这套体系管理"制品保鲜度"的完整闭环。

实践速查

  • 全量巡检:node .trae/skills/impeccable/scripts/doctor.mjs --json
  • 指定目标(monorepo):追加 --target <path>
  • 应用无判断的自动修复:node .trae/skills/impeccable/scripts/doctor.mjs --fix(只处理 auto);
  • 工具版本过时:走 npx impeccable update,不归 doctor 管;
  • 真相漂移:不靠脚本判定,把具体缺口交接给 document/init
  • 关闭每周启动巡检:.impeccable/config.json"stalenessCheck": false 或单次会话设 IMPECCABLE_NO_STALENESS_CHECK=1
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.74 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.81 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
595
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.63 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
518
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
389