文档 / 质量与治理
质量契约
质量规则保存在仓库中一个有版本记录的文件里,而不是写在提示词中,并且对人和智能体同样适用。
质量契约是项目中的 .ai/contract.json 文件。它定义了团队要求的严格程度:度量阈值、覆盖率、复杂度、更改规模、受保护的路径和豁免。
它由引擎的 gate、Git hooks、CI 和智能体共同执行。结果与代码由谁编写无关:人、Yuli、Claude Code、Codex、Kiro 或 Antigravity 都一样。
如果该文件不存在或无效,Yuli 会使用默认值(关键性为 业务)。每个字段都是可选的,因此部分填写的契约同样有效。
在哪里编辑
打开 治理中心(右侧边栏 → 更多工具,或在命令面板中使用 打开治理中心),然后进入 契约 标签页。
点击 保存并签名 保存时,Yuli 会使用你的 git config user.name 记录此次更改。你可以在 契约历史 中查看所有更改。
关键性
关键性会选定一整套阈值配置。共有四个级别:
| 文件中的值 | Yuli 中的标签 | 适用场景 |
|---|---|---|
low |
低 | 原型、内部工具、实验。 |
business |
业务 | 业务应用。这是默认值。 |
regulated |
受监管 | 需要接受审计或监管的系统。 |
safety |
安全关键 | 一旦出错就会造成严重后果的软件。 |
配置档
| 阈值 | 低 | 业务 | 受监管 | 安全关键 |
|---|---|---|---|---|
| 验收分数 | 80 | 90 | 92 | 95 |
| 度量轮次 | 2 | 3 | 4 | 5 |
| 最低覆盖率 | 50 % | 70 % | 80 % | 90 % |
| 最大认知复杂度 | 20 | 15 | 15 | 10 |
| 最大圈复杂度 | 15 | 10 | 10 | 8 |
| 最低变异得分 | 0 % | 0 % | 60 % | 75 % |
| 每次更改的文件数 | 60 | 40 | 25 | 15 |
| 每次更改的行数 | 2000 | 1000 | 600 | 400 |
| 独立评审 | 否 | 否 | 是 | 是 |
| 阻止测试作弊 | 否 | 是 | 是 | 是 |
| 严格执行 | 否 | 否 | 是 | 是 |
你可以在 gates 中覆盖某个具体阈值。只会改变该字段,其余仍取自配置档。阻止测试作弊 和 严格执行 仅取决于关键性,无法覆盖。
契约中的验收分数和轮次会覆盖度量阶段的本地设置。
文件结构
{
"schemaVersion": 1,
"criticality": "business",
"gates": { "minCoverage": 75, "maxCyclomatic": null },
"changeLimits": { "maxFiles": 40, "maxLines": 1000 },
"protectedPaths": ["db/migrations/**"],
"waivers": []
}
| 字段 | 定义的内容 |
|---|---|
criticality |
low、business、regulated 或 safety。 |
gates |
acceptanceScore、maxMeasureRounds、minCoverage、maxCognitive、maxCyclomatic、requireIndependentReview、minMutationScore。null 表示取配置档的值。 |
changeLimits |
每次更改的 maxFiles 和 maxLines。 |
protectedPaths |
额外的 glob,会追加到默认受保护路径中。 |
waivers |
带到期日的豁免。 |
architecture |
分层(layers,包含 name、paths、mayDependOn)和 forbidCycles。 |
slos |
服务目标:latencyP95Ms、availability 或 errorRate。 |
licensePolicy |
允许(allow)和禁止(deny)的许可证,可按 SPDX 或按类别指定,例如 strong-copyleft。 |
reviewer |
独立评审者:requireOtherFamily、provider、model。 |
dataClassification |
数据模式及其级别:public、internal、confidential 或 restricted。 |
finops |
每个服务的月度预算及其负责人。 |
更改规模限制
更改规模通过 git diff --numstat 计算。锁文件(package-lock.json、yarn.lock、Cargo.lock、go.sum 等)计入文件数,但不计入行数。
在严格执行(受监管和安全关键)下,超出限制会阻止提交。在其他配置档中仅作警告。
受保护的路径
即使有人要求,智能体也无法编辑以下文件:
.ai/contract.json、.ai/quality.json和.ai/state/**.claude/settings.json和.claude/settings.local.json.githooks/**.github/workflows/**、.gitlab-ci.yml和JenkinsfileCODEOWNERS和.github/CODEOWNERS
匹配时不区分大小写。在 protectedPaths 中添加你自己的路径。从 Yuli 保存的契约更改会记入审计,并视为已批准。
豁免(waivers)
豁免允许以有理有据的方式临时跳过某条规则。
| 字段 | 内容 |
|---|---|
id |
豁免的标识符。 |
rule |
被豁免的规则:secrets、protectedPaths、testIntegrity、某种具体的作弊类型或 *。 |
path |
适用的 glob。为空表示任意路径。 |
reason |
原因。 |
approvedBy |
批准人。 |
expires |
到期日期,格式为 AAAA-MM-DD。 |
ticket |
可选的引用编号。 |
豁免在 expires 当天(含当天)之前有效。缺少日期或日期格式错误均视为已过期。到期后,规则重新生效,gate 会发出提醒。
在界面中,每个豁免都会显示其状态:有效、即将到期、已过期 或 日期无效。
testIntegrity 会一次性豁免所有测试作弊检测。请配合范围有限的路径和较近的到期日使用。
审计
每次保存都会在 .ai/state/contract-audit.jsonl 中追加一行,包含日期、作者、SHA-256 哈希和摘要(例如“criticality business→regulated; waivers +1”)。
作者始终是一个人:指定的姓名或你的 git config user.name。“Yuli”和“Yuli Code”会被拒绝作为作者。
下一步
- 与 N−1 对比度量:验收分数和轮次如何应用。
- Gate 与治理中心:如何在每次提交时强制执行契约。