关于 project-rules-architect
用于为 Agent 设计可执行且贴合项目的规则集。它根据项目选择专用模板,并区分规则、上下文文件与规划产物的归属。
主要功能
- 01探查项目并选择模板
- 02覆盖通用、领域与技术需求的规则
- 03分离上下文脚手架与规则集流程
- 04整理现有规则并适配代码库
- 05明确规则归属与文件间引用
- 06按目标衡量规则预算
适用场景
- 01为新项目创建 Agent 规则
- 02使规则适配现有代码库
- 03合并并去重规则文件
- 04与规划技能协作管理规则
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tleguede-works/ ship-clean-skills --skill project-rules-architect安装后在 Claude Code 中输入/project-rules-architect确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
provenance/synthesis-provenance.mdreferences/architecture-decision-guide.mdaudit-checklist.mdbaseline-scan.mddocumentation-sources.mdexisting-project-protocol.mdmdc-frontmatter-spec.mdmonorepo-strategy.mdpostmortems.mdresearch-summary.mdrule-file-template.mdstack-detection.mdtarget-formats.mdreferences/templates/core/architecture.mdcode-review.mdcoding-standards.mdentry-file.mdgit-workflow.mdquality-gates.mdsecurity.mdworkflow.mdreferences/templates/domain/accessibility.mddata-and-state.mddependency-security.mddesign-system.mderrors-and-loading-states.mdexternal-system-contracts.mdforms.mdi18n.mdperformance.md详细介绍
Project Rules Architect
生成 Agent 会实际遵循的规则集,而不是一份它会匆匆扫过、置之不理的风格指南。此技能旨在防止这样的失败:有人要求“列出所有规则,像资深开发者那样行事”,结果得到十五个详略不一的文件,其中一半相互矛盾,且没有接入任何地方,因此没有一条会被加载。六个月后,没人再信任这些规则,也没人愿意维护它们。
**解决方案的形式:**一个由专用规则模板组成的库——通用模板、按领域划分的模板,以及按技术划分的模板——通过探查项目来选择,而不是整套照搬。每项事实只存在于一个模板中。Agent 开始行动前所需的一切都放在入口文件中;其他内容则放在相关时才会加载的文件里。
每个会话开始起草前,先阅读一次 references/research-summary.md——其中包含以下每条原则背后的证据。当本次运行要整合现有规则、采用项目惯例或移植其他项目的模式时,阅读 references/postmortems.md。两者记录的都是真实且已发现的问题,而非假设。不要重新推导。
与规划技能协同工作
如果项目也使用规划技能(Forge,或任何管理 .forge/ 目录的同类技能),该技能会被调用两次,且两次都由规划技能发起。它是被调用方,不负责路由。
| 调用 | 时机 | 产出内容 |
|---|---|---|
| 上下文框架 | 项目开始时,技术栈尚未确定 | 四个上下文文件,除此之外不产出任何内容 |
| 规则集 | 规划技能确定技术栈和项目目标后 | AGENTS.md + 规则,并接入目标环境 |
**这四个框架文件是项目跨会话记忆,两个技能之后都不得再写入它们。**由 Agent 维护:追加会话记录、记录决策、记下修正。框架调用之后,Forge 和本技能都不得编辑这些文件,也不得各自保留一份副本。
原因不在于整洁。记忆文件是唯一一个价值会跨会话累积的产物,因此也是最容易被两个写入者破坏的产物:一个追加,另一个覆盖,而损失不易察觉,因为文件依然存在,看起来也还算合理。
| 本技能负责 | 规划技能负责 |
|---|---|
一次性确定 AGENTS.md、SESSION_LOG.md、DECISIONS.md、LEARNINGS.md 的结构 | 产品、技术栈、架构、计划 |
AGENTS.md、{{rules dir}}/*.md——需要遵循的内容 | .forge/*.md——要构建的内容,以及项目所在位置 |
接入文件(opencode.json、.cursor/ 等) | state.json——状态、路径、ID、哈希 |
| — | .forge/audit/——规划过程中的事件 |
**规则:每项事实只存在于一个文件中,每个决策都必须有负责人。**规划技能的状态文件存放指针,而不是副本。包含散文内容的状态文件就不再是状态文件——它是一份缺乏规范的文档,既无法排序,也无法索引,而且出错时不会发出任何信号。
这对本技能自身工作有两点影响:
- **修正必须注明目标位置。**记录在
LEARNINGS.md中的任何内容,都要说明将被提升到哪个规则文件中。没有目标的修正无法得到提升。参见postmortems.md案例 5。 - **两次调用相互独立,彼此都不意味着对方也已发生。**项目可以有框架而没有规则——这是两次调用之间的正常状态,并不代表规则集只完成了一半。反过来,项目也可以有规则而没有框架,这对于单独使用本技能的人来说很常见。两种缺失都不应被报告为缺陷。
六项原则
本技能产出的所有内容都必须遵循这些原则。若草稿违反其中任何一项,应修改草稿,而不是原则本身。
-
**操作性策略,而非文档——分为三个层级,而不是两个。**在决定删减之前,先将每句话准确归入以下一个类别:
层级 测试标准 示例 处理方式 教程性文字 解释模型在训练中已学到的内容 用 20 行示例说明什么是服务器组件 删除 操作性文字 回答“遇到 X 时,Agent 应该怎么做?”或“X 是否可接受?”——即使没有反引号命令 “按职责拆分,而不是按行数拆分——单个文件有 250 行,只要职责单一就没问题” 保留。 尽可能精简改写;不要删除。 可验证的命令 可直接执行且有通过/失败结果的命令 npm run lint以 0 退出保留 对中间层级的测试标准是:你能想象 Agent 违反这条规则吗? 如果能, 那它就是决策规则,而不是文档,无论是否包含命令。“我们重视整洁的代码” 不符合——没有什么可以违反。“按职责拆分,而不是按行数拆分”符合——Agent 很容易为了达到行数限制,错误地拆分一个有 250 行的文件。
-
一条事实只出现在一个位置。 永远不要在两个文件中陈述同一条规则。如果 规则适用于多个场景,就只能放在一个模板中,其他所有地方都按名称引用。这是 造成错综复杂的最大原因——不是单条规则本身不好,而是同一条规则随着时间推移 在两个地方变成不同说法,最终彼此矛盾。审查时用 grep 搜索,而不是凭主观判断, 并且交叉引用必须指向具体章节,而不是文件。“参见
security.md”不够明确; “参见security.md§令牌处理”在文件重构后仍然有效。 -
优先级要排序,而不是堆叠。 如果“快速交付”+“全面覆盖”+“5 分钟的 CI 预算”没有优先顺序,Agent 就会自行选择,而你会在事后才发现。任何可能 发生冲突的规则,都必须在入口文件中明确排序,其他文件均引用该顺序。
-
仅针对全新的规则集,从骨架开始,根据修正逐步扩展——共有四种情况,而 不是两种。
- 上下文框架(明确要求创建,且尚未确定技术栈):输出记忆和上下文结构, 然后停止。不添加规则、不创建规则集、不探测技术栈。参见下文“上下文 框架”一节——规划技能会首先调用这种模式,处理不当会带来高昂代价。
- 初始化(没有现有规则):提供精简、正确的骨架,并附上持续积累经验的 一节。第一天不要列举所有假设性规则——这会带来随机性问题,也就是猜测 尚未发生的情况。
- 整理(重组现有规则):每条现有规则都代表已吸取的经验。重新组织并
去重;不要删减内容。 在这种情况下施加“保持精简”的压力,恰恰会导致
postmortems.md案例 1 中那样的内容悄然丢失。未经询问即可删除的内容 仅限教程性文字和真正重复的内容。 - 采用(已有代码,无论是否已有规则):完整执行
references/existing-project-protocol.md。检测代码实际采用的约定,然后 保留或迁移。技能此前没有处理这种情况,而这正是产生与运行中代码库 相矛盾规则的情况。
-
迁移模式不等于迁移内容。 模式可以迁移——什么情况会触发检查、验证 什么内容、记录到哪个文件。具体内容则不可以:文件名、库名、框架约定都属于 源项目,必须根据本项目的实际技术栈重新推导。规则文件若引用本项目中不 存在的文件、库或工具,就是内容污染(见
postmortems.md案例 2——另请 注意,搜索库名的 grep 无法发现流程相关词汇;还需要单独检查一次)。推论, 也是惨痛教训:生成的规则文件绝不能提及其源模板或配置档案的名称。 遗留的 “根据配置档案”或来自错误技术栈的框架符号,既是内容污染,也是悬空引用。 -
篇幅预算是说明文字的上限,也是门槛的下限。 这是两条不同的规则,把它们混为一谈,就会导致一组文件论证完整,却没有任何强制约束。
内容 预算 检验标准 说明文字 — 理由、背景、示例、历史 上限。优先删减 没有这句话,Agent 的行为会不同吗? 门槛 — 阈值、命令、退出码、禁用列表 下限。绝不删减 违反规则时,它会以非零状态退出吗? 不会以非零状态退出的门槛,就不是门槛。 它只是一句话,也和其他句子一样,难逃被忽略的命运:疲惫、赶时间,或被要求“赶紧做完”的 Agent,会直接略过它。阈值、命令和禁用列表是任何规则文件中成本最低的内容——每项只占一行——也是唯一能经受住这种压力的内容。
因此,如果这组文件超出预算,应先删减教程式说明文字;如果没有可删的内容,就增加范围更明确的文件,而不是删减操作性内容。 如果低于预算,也不代表可以继续删减——这说明应该追问缺少了什么,因为生成的文件组通常过于单薄,是由于触发了泄压机制(参见 § 步骤 0b)。
6b. 预算按目标分别计算,而且必须测量——回读测试无法检测超出预算的情况。
research-summary.md 中约 500 行的数字是 Cursor 自身的指导建议,且假设存在激活模式:只有打开相关文件时,范围限定的文件才会加载。这一建议不适用于没有范围限定机制的目标。
| 目标 | 范围限定 | 预算 | |
|---|---|---|---|
Cursor .mdc | 4 种激活模式 | 约 500 行始终生效内容 | mdc-frontmatter-spec.md |
OpenCode instructions glob | 无——每个文件在每次会话中都会加载 | 整个规则目录,严格总量限制 | 步骤 3b |
仅 AGENTS.md | 无 | 一个文件;如果超出一个文件的篇幅,就更换目标 | — |
对于没有范围限定机制的目标,拆分文件毫无用处。 无论如何,glob 都会加载这些文件。唯一能调整的是总量,以及不要把基于触发条件的内容放进无条件加载的文件中。
而且,步骤 6 中的回读测试无法发现超出预算的文件组。 它依据入口文件作答,而入口文件篇幅短、内容靠前——超出预算两倍的文件组也能通过测试。必须在步骤 3b 单独测量总量,否则就不测。
上下文脚手架
规划技能会在确定技术栈之前调用此模式。这是一项短路操作:输出四个上下文文件,不输出规则,然后停止。
| 输出 | 绝不输出 |
|---|---|
AGENTS.md — Agent 行动前所需的上下文,以及以下三个文件各自的触发条件 | 任何规则文件 |
SESSION_LOG.md — 发生的事情,按会话追加 | .opencode/rules/ |
DECISIONS.md — 已做出的决策,以及以问题形式列出的待解决问题 | 技术栈选择 |
LEARNINGS.md — 修正内容,每项都注明将提升到哪里 | 探测结果 |
格式具有规范性——应按原样复现,不要重新设计
这 4 个文件有固定格式,因为如果一份记忆的格式因项目而异,那么第二次会话时就没人看得懂。它们的完整内容写在 templates/memory/ 中;该目录不是示例,而是规范。
这些格式曾被保留,后来却丢失了:provenance/synthesis-provenance.md
记录了,包含 8 个字段的 SESSION_LOG.md 和包含 6 个字段的 ADR 表单“原样保留”,并且“与条目文件一同输出”。但从未输出过 templates/ 目录。后果不是预测出来的,而是实际测量得出的——在一个从 Phase 0 完整运行到 Phase 5 的项目中,脚手架生成了只有 4 个项目符号的日志、一个只有问题而没有任何已结论决策的 DECISIONS.md,以及一个没有任何条目的 LEARNINGS.md。格式已知,也有文档记录,却不具备规范性,因此每个项目都各自为政。
| 文件 | 格式 | 最常丢失的字段 |
|---|---|---|
SESSION_LOG.md | 按顺序排列的 8 个命名字段:STARTED FROM · DECIDED · REJECTED · BLOCKED · FILES TOUCHED · STATUS · NEXT SESSION SHOULD · NEXT SESSION SHOULD NOT | REJECTED——见下文 |
DECISIONS.md | ## ADR-<NNN>: <title>,包含 6 个字段:Date · Statut · Contexte · Décision · Alternatives considérées · Conséquences | Alternatives considérées |
LEARNINGS.md | 每条纠正占一行,以对照形式写出错误,然后写 → domaine: … | Seen: … | 对照形式 |
AGENTS.md | 上下文,然后是包含描述和触发条件的索引 | 触发条件 |
REJECTED 是最能体现价值的字段。其他字段都记录了已完成的事情;REJECTED 记录了拒绝了什么以及原因,并且只有它能阻止后续会话再次提出同一建议。没有它的日志会反复争论过去的决定:在上文提到的那个项目中,被拒绝的内容包括合同约定的排除项(会计、银行卡支付)、有意不规划的 6 个切片、client-liaison 拒绝的 16 件事,以及两条臆造的 Agent 路径。这 4 类内容都至关重要,却没有任何地方可以记录。
已结案的决策就是已结案。DECISIONS.md 是已结案决策的只追加登记簿。“只追加”和“已结案”合起来意味着:如果某项决策后来被证明有误,就应新增一份 ADR,明确指出它取代了旧 ADR,绝不能悄悄改写。应使用 Statut: Actif 或 Statut: Supersédé par ADR-<NNN>;每个条目都必须有 Statut: 行,因为没有该行的条目无法被取代,也就无法纠正。
项目目前还无法回答的问题也应作为问题记入 DECISIONS.md,并且每个问题都应注明将促使其结案的触发条件。但登记簿的职责是记录已结案决策:如果 DECISIONS.md 只有未解决的问题而没有已结案决策,就没有记录任何约束未来会话的内容。
索引的两部分,以及通常缺失的那一部分
AGENTS.md 包含一张表,每个文件对应一行。每行需要两项内容,
而且两者并不相同:
| 部分 | 回答的问题 | 缺少它意味着 |
|---|---|---|
| 描述 | 这个文件要写什么? | 文件内容成谜 |
| 触发条件 | 什么情况会让我写入这个文件,以及何时写? | 文件会永远空着 |
一行有描述却没有触发条件,是最容易犯的错误,因为表格看起来完整。 但它并不完整:它只是列出了四个容器,却没有说明如何填充它们。结果就是 一份记忆虽然已经创建、结构合理、命名正确,却永远空空如也——这 比没有记忆更糟,因为它看起来像是有了进展。
触发条件是一个条件,而不是类别。“纠正”是描述。 “当你连续两次犯同一个错误时”才是触发条件。三者都需要触发条件, 而且必须是 Agent 能自行识别的时刻,不需要重新阅读文件来判断触发时机 是否已到。
AGENTS.md 本身不需要触发条件:它会被加载,因此它就是触发其他三个文件
的依据。
为什么脚手架里放的是问题,而不是决策。 这是将原则 2 应用于时间,
而不是位置:在尚未了解技术栈时记录的决策并非决策,而是穿着决策外衣的
猜测。PRA 自身的规则——无法提供来源的说法应成为问题、拟议的 ADR 或
未确认条目,绝不能成为带有保留意见的规则——也是同一条规则。因此,
DECISIONS.md 以项目当前无法回答的问题开篇,而第一条目的
Status: 为 Open。
为什么脚手架不是规则集。 规则集要等到了解技术栈后才会创建,并且 会针对该技术栈生成。如果脚手架里已经包含规则,要么就必须整体重写, 要么——更糟的是——与这些规则并存并被加载两次。每条事实只能有一个归属, 而在这个阶段,事实都是问题。
之后由谁写入这些文件:不是此技能,也不是规划技能。 它们是项目 跨会话记忆,由 Agent 维护。此技能的工作在四个文件创建完成且结构正确时 就结束了——包含所需标题,并且每个文件中都有一个用于记录纠正内容的规范位置。
在宣布完成前进行验证,因为这种错误不会显现,而且有问题的脚手架 看起来与空脚手架一模一样:
- 四个文件都存在于项目根目录,并且包含各自的标题。
AGENTS.md对三个文件中的每一个都提及两次:一次说明它保存什么, 一次说明什么条件会触发写入。 只有描述而没有触发条件,就只是一个 没有填充说明的容器。LEARNINGS.md中只有一个用于追加纠正内容的位置——审计时,如果文件 提供了两个位置,就已经会判定不合格,因为 Agent 读取的会是过时的那一半。DECISIONS.md中的条目都带有Status:行。脚手架自带条目的状态为Open。- 没有文件包含规则、阈值、命令或版本固定项。如果有,脚手架就变成了第二套 规则集。
- 四个文件之间的每一处交叉引用都使用准确的大写文件名。
AGENTS.md引用的是DECISIONS.md,而不是decisions.md——在区分大小写的 文件系统上,小写名称无法解析到任何文件,而且引用会在有人跟进时悄无声息地 失效,那往往已经是几个月之后了。检查正文,不要只检查表格:这两处可能分别 出现大小写错误。 - 条件分支都已处理。 见下文。
此模式中的唯一条件判断,以及它存在的原因
templates/memory/ 中只有一个 {{#if forge-present}} 代码块,位于 AGENTS.md
和 SESSION_LOG.md 的所有权表中。
通过检查文件系统来判定:如果项目根目录下存在 .forge/ 目录,就保留代码块;否则删除。 这里没有模板引擎,也不需要再添一个东西来维护。
这正是关键所在。 这些代码块过去是无条件的,因此会把
.forge/conventions.md、.forge/architecture.md、.forge/state.json 和 .forge/audit/issues.md 列为存放技术栈信息的位置——但项目实际上根本没有 .forge/,而对于单独使用此技能的用户来说,这是常见情况。这并不是一个无伤大雅的悬空链接:它是每个会话最先加载的文件中的错误指令,会在 Agent 构建项目概况时,告诉它技术栈信息存放在一个实际并不存在的位置。
单独使用才是常见情况,因此没有其他内容时,单独使用分支必须能正确阅读。
检查两个方向。 为没有 .forge/ 的项目生成脚手架,并确认没有 .forge 字符串残留;然后为存在 .forge/ 的项目生成,并确认其中包含相关引用。rules-selftest.js §no_forge_coupling 会自动检查第一个方向——第二个方向没有可供运行的项目,因此只能通过阅读检查。
模板库
references/templates/——分为三层。你从中选择,不会照搬全部内容,也不会在运行期间编辑它。
| 层级 | 目录 | 生成内容 |
|---|---|---|
| 核心 | templates/core/ | 始终生成。八个文件:入口文件、架构、工作流、git 工作流、质量门禁、代码审查、编码规范、安全 |
| 领域 | templates/domain/ | 根据检测结果选择。十一个文件:数据与状态、错误与异步状态、表单、UI 组件、无障碍、测试、依赖项安全、性能、i18n、设计系统、外部系统契约 |
| 技术 | templates/tech/ | 根据检测结果选择。八个覆盖文件,另加 tech/variants/ 中的四个变体差异文件 |
为什么核心模板是八个,以及新增第九个模板必须满足什么条件。 这些是适用于任何语言、任何项目的规则,或者是决定其他任何规则能否执行的规则。第二部分才是关键:quality-gates.md 负责定义让其余规则可检查的命令,而缺少它的模板集包含的规则将无法验证——这正是此技能要防止的问题。
第九个模板也必须达到同样的标准,而“这是个不错的主题”并不算标准。标准是:每个项目在采取行动前都需要它吗?或者每个项目在检查自己是否正确采取了行动前都需要它吗?
选择是查表,而不是主观判断——references/stack-detection.md
是对应的表格,每个生成的模板都会记录触发它的信号。每个未生成的模板都会记录排除它的表格行。“未配置测试运行器”是值得指出的问题;沉默不是可以接受的理由。
变体是差异文件,而不是替代品。 变体会说明哪些文件要改动,以及如何改动。应用两个变体就意味着应用两个差异文件——绝不编写组合变体,也绝不让差异文件重述它所修改的内容。
如果你需要了解某个模板为何采用当前形式——因为你要修改或新增模板,或检查某项更改会删掉什么——请阅读
provenance/synthesis-provenance.md。它将三个源项目中的每条规则映射到相应模板,并说明哪些内容被合并、去重、删减,哪些内容保留为项目特有。
运行时不会读取它。 它是产生此模板库的整合过程的审计记录,共有 441 行历史内容。将它放在 references/ 中,并要求每次运行都读取它,是个错误:库中的文件就是 Agent 会读取的文件,而这个文件没有反复读取的价值。
工作流
步骤 0b — 扫描,并让扫描结果决定
在步骤 1 之前,以及写下任何阈值之前运行此步骤。 流程见
references/baseline-scan.md;要运行它,不要只读一遍再描述。
扫描一次即可回答三个问题,而过去这三个问题都靠猜:
- 具体使用了什么技术栈? — 根据清单文件解析,而不是凭印象判断。
- 项目今天是否处于绿色状态? — 运行每一道门禁,并捕获输出。如果项目的 lint 已经报红,却仍在该项目上编写规则集,就必须说明这一点;否则其完成定义一开始就是红色的,第一天就会被忽略。
- 是
greenfield还是ratchet? — 根据扫描结果得出,绝不询问。 询问会让模式变成一种偏好;推导则会让它成为一种结果,而同一仓库运行两次得出的结果必然相同。
通过访谈决定的模式会随 Agent 的心情以及问题的措辞而变化。正是这种差异,导致同一模板库在一个项目上生成 6 个文件的规则集,在另一个项目上却生成 17 个文件。
将结果写入 docs/quality-baseline.md — 这是项目产物,不属于规则集 — 并按流程规定的六行格式报告。
“未安装该命令”也是一种结果。 将其记录为 absent,提出安装建议,并输出该状态的门禁。绝不要写下任何未由命令生成的基线数字。
步骤 1 — 探测,然后访谈
如果调用方要求生成上下文脚手架,到此为止,并运行 § 上下文脚手架。不要探测、不要扫描、不要访谈、不要生成技术栈。对于尚未确定技术栈的项目进行探测,会产生一个清单匹配结果和一张无可匹配内容的领域行表格 — 一份看似可靠、实则毫无意义的报告;而这正是此模式要避免的。
否则,采用扫描解析出的技术栈,运行检测探针
(stack-detection.md),匹配表格,并生成建议的模板集。不要询问仓库中已有的信息。
然后只询问探测无法确定的信息。 通常只需一两个问题:
- 目标格式 — 唯一无法推断的问题。参见
references/target-formats.md。如果用户已经说明偏好的结构,那就是规范,而不是有待改进的默认选项。 - Git 策略 — trunk-based、git-flow 或 release-train。此项同样无法推导:两种分支方式都有代价,而且无法以相同程度撤销。如果用户没有偏好,选择 trunk-based 并将其记录在
DECISIONS.md中;“不采用任何策略”是唯一无人能撤销的选项。 - 属于决策而非检测结果的变体 — 路由器、渲染策略、是否需要状态库。组件库这一维度由已安装的内容决定;数据访问这一维度属于决策,因此要询问。
- Monorepo 还是单个应用,如果是 Monorepo,还要询问包含哪些包
(
references/monorepo-strategy.md)。 - 团队还是个人开发 — 这会影响第一天搭建脚手架的投入是否值得。
- 任何已经确定的事项 — 已定方案、现有记忆系统、设计契约、部署方案。
如果用户说“给 X 随便生成一个合理方案”,不要强行进行访谈。 说明你将采用的假设,然后继续。只确认那些会悄无声息地导致架构错误的事项 — 目标格式就属于这种情况。
不要询问阈值。 阈值由 baseline-scan.md § 模式选择决定;询问会重新引入扫描旨在消除的差异。
Step 2 — 对照真实来源进行验证
在编写任何技术专属规则之前,先按顺序查阅
references/documentation-sources.md。 首先查看项目本身——清单中的确切版本、已安装的源代码、随附的类型定义。然后查看框架为 Agent 打包的内容。接着检查已配置的 MCP 服务,而不是想当然地认为它们存在。然后查阅与精确锁定版本相对应的官方文档。再查看已安装 CLI 自带的帮助信息。最后才进行网络搜索。
每条技术专属声明都必须带有来源标记,注明它来自哪个层级;否则就必须将其标记为附有 ADR 的项目决策。 无法找到来源的声明应改为一个问题、一份拟议的 ADR,或 external-system-contracts.md 中一条未确认的条目——绝不能将其写成带有模糊措辞的规则。“可能是 X,但请核实”既有规则的权威性,又有猜测的可靠性,而 Agent 会照此行事。
不要因为熟悉该框架就跳过此步骤。 它要防止的问题往往难以察觉:代码能够编译,看起来也符合惯用写法,却调用了两次版本更新前就已变更的 API。
Step 3 — 选择模式
运行模式探测(existing-project-protocol.md §模式检测)。这是一项查找操作:
- 不存在指令文件 → Step 4。
- 存在指令文件 → 运行完整的现有项目协议,尤其是Step A:在起草任何规则之前,先检测项目实际采用的约定。 阅读代码,而不是清单。用
file:line引用记录每项约定。生成差距报告并展示给用户,让用户针对每个维度选择保留项目约定还是分阶段迁移。与现有可运行实现相矛盾的规则,比没有规则更糟——Agent 要么遵循规则并破坏代码,要么遵循代码并不再信任整个文件。
只有 README、没有指令文件的项目属于引导初始化,而非规则采用。 README 是文档,不是规则。
对于尚无代码的项目:探测只会匹配清单,不会匹配其他内容。每个有条件的领域信号——表单、测试运行器、本地化层、设计契约、外部系统——都需要已有代码。因此在项目第一天,探测只会返回核心层级及清单中提及的内容,领域选择也就需要提问,而不是查找。应明确说明这一点,而不是展示一张实际上没有任何匹配项的表格;也不要把第一天的缺项报告为发现——“尚未配置测试运行器”虽属实,但在任何代码都还不存在之前毫无意义。
Step 3b — 在交付前衡量规则集的规模
# the target's actual instruction surface
find .opencode/rules -name '*.md' -exec cat {} + | wc -l
wc -l AGENTS.md
将其与 Step 1 中所选目标的预算(原则 6b)进行比较。如果超出预算:
- 将基于触发条件的内容移出始终加载的文件。 仅在差异涉及身份验证时适用,或仅适用于单体仓库中的某个服务的章节,却需要在每次不适用的会话中照样付出开销。对于按 glob 加载的目标,这是唯一有效的调整方式。
- 精简说明文字,绝不精简规则。 如果必须缩减规则,应先删去解释理由的从句,而不是删去阈值、命令或禁令。
- 最后才删减完整规则,并且只删教程性文字。预算是上限,不是目标——但规则集超出上限两倍属于缺陷,而非详尽。
第 4 步 — 起草
填写每个选定的模板。以下三点需要把握:
- 章节顺序固定,并按优先级排列:命令 → 完成定义 → 升级处理 → 按任务组织的章节 → 版本与禁止模式 → 最后是风格。Agent 需要先知道如何构建,之后才需要知道如何排版。风格排在最后,也是最先删减的内容。
- 按任务组织章节,而不是堆砌平铺的项目符号——“编写 X 时”、“审查 X 时”。操作性文字中的决策规则就在这些章节里;平铺成列表后,它们最容易丢失。
- **指出代码库中的一个规范示例,而不是粘贴代码示例。**粘贴的代码会悄无声息地过时;文件引用不会。
- **在规则中用一个分句说明原因。**模板中的
GENERATOR NOTES块在生成时会被删除,因此,Agent 要将规则应用到模板未预料到的情况时所需的信息,必须写在规则本身上(rule-file-template.md§The Generator Notes contract)。推导过程属于注释;应用方式属于规则。
三种操作,不能互换——合并任何内容前,先明确自己要执行哪一种:
| 操作 | 结果 | 适用情况 |
|---|---|---|
| 吸收 | 将完整内容以相当的详尽程度转移到目标中;删除源内容,因为它现在已存在于目标中 | 源内容中的规则确实属于目标的范围 |
| 引用 | 保留源内容;目标按名称和章节指向它 | 源内容过长或过于具体,不适合直接内嵌 |
| 用 grep 或一句话替代实质性规则 | **绝不允许。**这只是伪装成结构调整的静默内容丢失 |
吸收任何内容后,立即核验——在继续处理下一个文件之前,趁源文件仍打开时完成:
- 列出源文件中的每条独立规则:编号条目、阈值、禁止模式、决策规则。不只是命令。
- 确认目标文件中以相当的详尽程度包含了每条规则——使用完整句子或可强制执行的命令,而不是顺带一提。
- **如果规则数量减少了,那就是有内容丢失了,而不是经过了精简。**源文件有 94 行,目标文件中却只有三条项目符号,这是警示信号,不是成功。
第 5 步 — 审计
A 部分是一条命令。阅读任何内容之前先运行它。
node "$PRA/scripts/rules-selftest.js" <project>
十项确定的检查——连线、索引、占位符、交叉引用、相互矛盾的阈值、.forge/ 耦合、污染、无法执行的文字、门槛、预算。**失败就是缺陷,不是讨论。**修复后重新运行。
脚本自身的自测(node "$PRA/scripts/selftest.js")证明每项检查都能检测其声称能检测的问题,因此通过就是证据,不是走形式。
然后执行 B 部分,即 references/audit-checklist.md 中需要判断的部分。不要将其自动化;未核实的内容不要报告为已核实。以下各部分能发现其他检查无法发现的问题:
- 内容保留——适用于合并。冗余和矛盾检查会将新集合与自身进行比较;一个集合可以完全没有冗余,却丢失了三分之一的规则。需要进行对账统计:*"保留了 N 条规则,通过交叉引用吸收了 M 条,删减了 K 行教程文字(列出)。"*如果无法给出这个数字,就说明你还没有检查。
- 跨项目污染——适用于采用或移植。A 部分会发现机械层面的问题;这部分则能发现语义层面的问题,即借用的想法用本项目的词汇表达,因此看起来像是原生内容。
- 与代码矛盾——适用于采用。对每条规则,都要确认代码没有以关键方式执行相反的操作。其他检查都发现不了这一点,因为这项检查是将规则集与代码库比较,而不是与自身比较。
- 来源依据——每项特定于技术的声明都能追溯到阶梯中的某一级或某个 ADR。
- 提升——适用于有
external-system-contracts.md的项目:不得有尚未承诺的发现紧挨着与其矛盾的规则;任何已连续多次会话普遍成立、却尚未进入规则文件的发现也不得遗漏。 - 分歧——适用于合并,或带有迁移过程的采用:每项已检测到的分歧都必须是保留规则或迁移目标。未作交代的分歧,就是被悄然删除的规则。
**还要检查:**每条“始终适用”的规则确实适用于每个会话,而不是暗中有所限定;每一对冲突的优先级都已排序;没有任何指令无法通过全部四项可检查性测试(命令、glob 匹配、禁用列表查询,或原则 1 的“Agent 会违反这条规则吗?”测试)——重写未通过的指令,不要看到就删掉;每个文件的行数都作为上限;索引引用了每个文件;生成的索引列出了所有生成的文件,且没有其他文件。
步骤 6 — 接入、交付并建立反馈循环
接入目标格式——这是交付内容的一部分,不是后续事项。
生成 Markdown,却没有让工具加载它的文件,只会得到一套看似完整、实际完全不起作用的规则集(target-formats.md)。
合并,绝不覆盖。 现有配置文件包含用户的模型、提供商和工具配置。添加键,不要替换文件。
在宣布完成前验证接入情况:配置文件可以解析;其中指向的每个路径都存在;匹配不到任何内容的 glob 也是有效配置,只是什么都不会加载。
然后告诉用户三件事:
- 持续积累的经验教训放在哪里——一个唯一的权威位置。只有 Agent 连续两次出错时,才添加一条纠正规则,不要凭空推测。如果项目已有跨会话记忆系统,就把经验教训接入其中,而不是另建一套并行机制。
- 回读测试。 在一个全新的会话中,询问 Agent 项目的构建命令、完成定义,以及哪些规则文件适用于某个指定领域。如果它答不上来,说明文件太长、太含糊,或未被发现。先修复这个问题,再添加更多内容——接入出了问题时,更多规则只会变成更多无法加载的规则。在采用模式下,还要多问第四个问题:这个项目本身遵循什么模式? 如果答案描述的是模板,而不是项目本身,说明规则有误。
- 审计结果,按步骤 5 中的核对格式给出。
如果模板有误——某项技术叠加方案中的机制不适用,或领域模板中的规则在实际项目中行不通——就修复模板文件,而不只是已交付的输出。 下一个项目会复制模板。若不在那里应用修正,就帮不到任何人,同样的缺陷还会再次交付。
各模式需要读取的内容
读取错误的子集,会导致同一任务的两次运行产生不同输出。只阅读此表中的内容,别无其他,除非模式发生变化,或某一行注明“按需”。
| 文件 | 上下文搭建 | 引导 | 整合 | 采用 |
|---|---|---|---|---|
SKILL.md | ✔ | ✔ | ✔ | ✔ |
baseline-scan.md | — | ✔ | ✔ | ✔ |
postmortems.md | — | ✔ | ✔ | ✔ |
stack-detection.md | — | ✔ | ✔ | ✔ |
documentation-sources.md | — | ✔ | ✔ | ✔ |
target-formats.md | — | ✔ | ✔ | ✔ |
monorepo-strategy.md | — | monorepo | monorepo | monorepo |
research-summary.md | — | ✔ | — | — |
existing-project-protocol.md | — | — | — | ✔ |
audit-checklist.md | § 验证以上内容 | 步骤 5 | 步骤 5 | 步骤 5 |
rule-file-template.md | — | 按需 | 按需 | 按需 |
architecture-decision-guide.md | — | 按需 | 按需 | 按需 |
mdc-frontmatter-spec.md | — | 仅限 Cursor | 仅限 Cursor | 仅限 Cursor |
provenance/synthesis-provenance.md | 绝不 | 绝不 | 绝不 | 绝不 |
每种会生成规则的模式都会读取 baseline-scan.md,而且会在模式探测之前读取——扫描决定质量模式,在它所决定的事项已经确定后才读取协议,读取的理由就不对了。
有意让上下文搭建几乎不读取任何内容。 四个文件都基于一个决策编写——修正应放在哪里,问题应放在哪里——每个读取的参考资料都可能让规则意外混入。跳过 postmortems.md,因为在生成项目内容时存在污染风险,而此模式不会生成任何内容。
无条件读取 postmortems.md。 将模板复制到项目中本身就是一次跨项目移植——正是案例 2 讨论的操作——因此污染规则适用于所有模式,包括表面上纯粹进行增补的引导模式。
运行期间绝不读取 synthesis-provenance.md。 它是生成此资料库的一次性整合过程的审计记录。只有在维护资料库时才会读取它——例如添加模板,或判断某条规则是否通用。
参考文件
所有文件及其用途。上表说明了何时读取;这里说明的是用途,适用于按需查阅的条目。
templates/— 模板库。始终使用core/;根据检测结果使用domain/和tech/;tech/variants/用作差异补丁。baseline-scan.md— 起草前运行的测量环节:技术栈是什么、项目是否为绿色状态,以及使用greenfield还是ratchet。负责确定质量模式和基线产物。stack-detection.md— 选择表、排除项和报告要求。布局相关内容参见monorepo-strategy.md。monorepo-strategy.md— 仓库的包映射、构建工具、各包的命令发现方式,以及根目录与包之间的归属规则。existing-project-protocol.md— 模式检测、轻量和完整的约定检测流程、差距报告、保留与迁移的选择,以及迁移阶段。documentation-sources.md— 验证层级、引用要求,以及工具选择规则(只有已安装、受维护且退出码非零的工具才会成为门禁)。target-formats.md— 各环境的入口文件、规则位置、接线文件和钩子配置。负责单体仓库的接线。rule-file-template.md— 章节骨架及排序、章节标记约定,以及模板绝不能包含的内容。architecture-decision-guide.md— 文件组织和激活模式的决策树。格式相关问题参见target-formats.md。audit-checklist.md— A 部分是脚本,B 部分是判断。postmortems.md— 实际发现的问题及其促成的修复。每种模式下都要阅读。research-summary.md— 原则背后的证据,在引导流程中每个会话阅读一次。mdc-frontmatter-spec.md— Cursor.mdcfrontmatter、四种激活模式及优先级。../provenance/synthesis-provenance.md— 将每条源规则映射到对应模板,并说明合并、去重、删减的内容,以及保留为项目专属的内容。人工维护;运行时绝不读取。
脚本
| 脚本 | 功能 | 运行时机 |
|---|---|---|
scripts/rules-selftest.js | 对已交付的规则集执行十项确定性检查:接线、索引、占位符、交叉引用、相互矛盾的阈值、.forge/ 耦合、污染、无法执行的文本、门禁、预算 | 第 5 步,以及第 6 步之后再次运行 |
scripts/selftest.js | 在合成的损坏规则集上,验证上述十项检查都能检测到各自声称的问题 | 更改检查项之前 |
之所以编写此脚本,是因为审计清单不值得信赖。 清单中的每项要求都可以确定性判定,而用散文描述的确定性要求,Agent 无需运行任何检查,就能报告已满足该要求。实际测得:交付的规则集内部一致、接线清晰,却缺少所有质量门禁——而且按照清单的原样执行时,它通过了审计。
编辑任一脚本后,都要运行 scripts/selftest.js。 悄然变得过于宽松的检查项会对所有内容都报告“一切正常”,而失败之所以不可见,恰恰是因为工具仍然能运行。