dev-playbooks-cn 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +466 -0
- package/bin/devbooks.js +987 -0
- package/package.json +43 -0
- package/skills/Skills/344/275/277/347/224/250/350/257/264/346/230/216.md +446 -0
- package/skills/Skill/345/274/200/345/217/221/346/214/207/345/215/227.md +248 -0
- package/skills/_shared/context-detection-template.md +315 -0
- package/skills/_shared/mcp-enhancement-template.md +144 -0
- package/skills/_shared/references//351/200/232/347/224/250/345/256/210/351/227/250/345/215/217/350/256/256.md +114 -0
- package/skills/_template/config-discovery-template.md +126 -0
- package/skills/devbooks-brownfield-bootstrap/SKILL.md +167 -0
- package/skills/devbooks-brownfield-bootstrap/references//344/273/243/347/240/201/345/257/274/350/210/252/347/255/226/347/225/245.md +203 -0
- package/skills/devbooks-brownfield-bootstrap/references//345/255/230/351/207/217/351/241/271/347/233/256/345/210/235/345/247/213/345/214/226.md +96 -0
- package/skills/devbooks-brownfield-bootstrap/references//345/255/230/351/207/217/351/241/271/347/233/256/345/210/235/345/247/213/345/214/226/346/217/220/347/244/272/350/257/215.md +115 -0
- package/skills/devbooks-brownfield-bootstrap/references//346/234/257/350/257/255/350/241/250/346/250/241/346/235/277.md +42 -0
- package/skills/devbooks-brownfield-bootstrap/scripts/cod-update.sh +357 -0
- package/skills/devbooks-brownfield-bootstrap/templates/project-profile-template.md +172 -0
- package/skills/devbooks-c4-map/SKILL.md +151 -0
- package/skills/devbooks-c4-map/references/C4/346/236/266/346/236/204/345/234/260/345/233/276/346/217/220/347/244/272/350/257/215.md +33 -0
- package/skills/devbooks-c4-map/references//345/210/206/345/261/202/347/272/246/346/235/237/346/243/200/346/237/245/346/270/205/345/215/225.md +185 -0
- package/skills/devbooks-code-review/SKILL.md +175 -0
- package/skills/devbooks-code-review/references/PR/346/250/241/346/235/277/344/270/216/346/214/207/345/215/227.md +321 -0
- package/skills/devbooks-code-review/references//344/273/243/347/240/201/350/257/204/345/256/241/346/217/220/347/244/272/350/257/215.md +100 -0
- package/skills/devbooks-code-review/references//345/235/217/345/221/263/351/201/223/351/200/237/346/237/245/350/241/250.md +495 -0
- package/skills/devbooks-code-review/references//350/265/204/346/272/220/347/256/241/347/220/206/345/256/241/346/237/245/346/270/205/345/215/225.md +311 -0
- package/skills/devbooks-coder/SKILL.md +219 -0
- package/skills/devbooks-coder/references//344/273/243/347/240/201/345/256/236/347/216/260/346/217/220/347/244/272/350/257/215.md +70 -0
- package/skills/devbooks-coder/references//344/275/216/351/243/216/351/231/251/346/224/271/345/212/250/346/212/200/346/234/257.md +275 -0
- package/skills/devbooks-coder/references//346/227/245/345/277/227/350/247/204/350/214/203.md +329 -0
- package/skills/devbooks-coder/references//347/274/226/347/240/201/351/243/216/346/240/274/347/273/206/345/210/231.md +351 -0
- package/skills/devbooks-coder/references//351/224/231/350/257/257/347/240/201/350/247/204/350/214/203.md +463 -0
- package/skills/devbooks-delivery-workflow/SKILL.md +217 -0
- package/skills/devbooks-delivery-workflow/references//344/272/244/344/273/230/351/252/214/346/224/266/345/267/245/344/275/234/346/265/201.md +256 -0
- package/skills/devbooks-delivery-workflow/references//345/216/237/345/236/213-/347/224/237/344/272/247/345/217/214/350/275/250/346/250/241/345/274/217.md +168 -0
- package/skills/devbooks-delivery-workflow/references//345/217/230/346/233/264/351/252/214/350/257/201/344/270/216/350/277/275/346/272/257/346/250/241/346/235/277.md +133 -0
- package/skills/devbooks-delivery-workflow/scripts/ac-trace-check.sh +330 -0
- package/skills/devbooks-delivery-workflow/scripts/audit-scope.sh +262 -0
- package/skills/devbooks-delivery-workflow/scripts/change-check.sh +1040 -0
- package/skills/devbooks-delivery-workflow/scripts/change-codemod-scaffold.sh +135 -0
- package/skills/devbooks-delivery-workflow/scripts/change-evidence.sh +152 -0
- package/skills/devbooks-delivery-workflow/scripts/change-scaffold.sh +442 -0
- package/skills/devbooks-delivery-workflow/scripts/change-spec-delta-scaffold.sh +136 -0
- package/skills/devbooks-delivery-workflow/scripts/constitution-check.sh +237 -0
- package/skills/devbooks-delivery-workflow/scripts/env-match-check.sh +128 -0
- package/skills/devbooks-delivery-workflow/scripts/fitness-check.sh +387 -0
- package/skills/devbooks-delivery-workflow/scripts/guardrail-check.sh +519 -0
- package/skills/devbooks-delivery-workflow/scripts/handoff-check.sh +141 -0
- package/skills/devbooks-delivery-workflow/scripts/hygiene-check.sh +340 -0
- package/skills/devbooks-delivery-workflow/scripts/migrate-from-openspec.sh +385 -0
- package/skills/devbooks-delivery-workflow/scripts/migrate-to-v2-gates.sh +202 -0
- package/skills/devbooks-delivery-workflow/scripts/progress-dashboard.sh +319 -0
- package/skills/devbooks-delivery-workflow/scripts/prototype-promote.sh +341 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-preview.sh +203 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-promote.sh +118 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-rollback.sh +124 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-stage.sh +117 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-all.sh +78 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-npm-package.sh +123 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-openspec-free.sh +81 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-slash-commands.sh +146 -0
- package/skills/devbooks-delivery-workflow/templates/handoff.md +50 -0
- package/skills/devbooks-design-backport/SKILL.md +73 -0
- package/skills/devbooks-design-backport/references//345/233/236/345/206/231/350/256/276/350/256/241/346/226/207/346/241/243/346/217/220/347/244/272/350/257/215.md +196 -0
- package/skills/devbooks-design-doc/SKILL.md +121 -0
- package/skills/devbooks-design-doc/references//345/276/256/346/234/215/345/212/241/350/256/276/350/256/241/346/270/205/345/215/225.md +149 -0
- package/skills/devbooks-design-doc/references//350/256/276/350/256/241/346/226/207/346/241/243/346/217/220/347/244/272/350/257/215.md +189 -0
- package/skills/devbooks-design-doc/references//351/232/220/347/247/201/345/220/210/350/247/204/346/243/200/346/237/245/346/270/205/345/215/225.md +240 -0
- package/skills/devbooks-entropy-monitor/SKILL.md +188 -0
- package/skills/devbooks-entropy-monitor/references//347/206/265/345/272/246/351/207/217/346/226/271/346/263/225/350/256/272.md +223 -0
- package/skills/devbooks-entropy-monitor/scripts/entropy-measure.sh +449 -0
- package/skills/devbooks-entropy-monitor/scripts/entropy-report.sh +303 -0
- package/skills/devbooks-entropy-monitor/templates/thresholds.json +99 -0
- package/skills/devbooks-federation/SKILL.md +264 -0
- package/skills/devbooks-federation/scripts/federation-check.sh +144 -0
- package/skills/devbooks-federation/templates/federation.yaml +89 -0
- package/skills/devbooks-impact-analysis/SKILL.md +135 -0
- package/skills/devbooks-impact-analysis/references//345/275/261/345/223/215/345/210/206/346/236/220/346/217/220/347/244/272/350/257/215.md +82 -0
- package/skills/devbooks-impact-analysis/scripts/graph-cache.sh +214 -0
- package/skills/devbooks-implementation-plan/SKILL.md +83 -0
- package/skills/devbooks-implementation-plan/references//347/274/226/347/240/201/350/256/241/345/210/222/346/217/220/347/244/272/350/257/215.md +99 -0
- package/skills/devbooks-index-bootstrap/SKILL.md +240 -0
- package/skills/devbooks-proposal-author/SKILL.md +83 -0
- package/skills/devbooks-proposal-author/references//346/217/220/346/241/210/346/222/260/345/206/231/346/217/220/347/244/272/350/257/215.md +66 -0
- package/skills/devbooks-proposal-challenger/SKILL.md +86 -0
- package/skills/devbooks-proposal-challenger/references//344/274/246/347/220/206/344/270/216/345/220/210/350/247/204/346/243/200/346/237/245/346/270/205/345/215/225.md +176 -0
- package/skills/devbooks-proposal-challenger/references//346/217/220/346/241/210/350/264/250/347/226/221/346/217/220/347/244/272/350/257/215.md +57 -0
- package/skills/devbooks-proposal-debate-workflow/SKILL.md +78 -0
- package/skills/devbooks-proposal-debate-workflow/references//346/217/220/346/241/210/345/257/271/350/276/251/345/267/245/344/275/234/346/265/201.md +24 -0
- package/skills/devbooks-proposal-debate-workflow/references//346/217/220/346/241/210/345/257/271/350/276/251/346/250/241/346/235/277.md +35 -0
- package/skills/devbooks-proposal-debate-workflow/scripts/proposal-debate-check.sh +102 -0
- package/skills/devbooks-proposal-judge/SKILL.md +78 -0
- package/skills/devbooks-proposal-judge/references//346/217/220/346/241/210/350/243/201/345/206/263/346/217/220/347/244/272/350/257/215.md +37 -0
- package/skills/devbooks-router/SKILL.md +346 -0
- package/skills/devbooks-spec-contract/SKILL.md +191 -0
- package/skills/devbooks-spec-contract/references/API/350/256/276/350/256/241/346/214/207/345/215/227.md +349 -0
- package/skills/devbooks-spec-contract/references//345/245/221/347/272/246/344/270/216/346/225/260/346/215/256/345/256/232/344/271/211/346/217/220/347/244/272/350/257/215.md +85 -0
- package/skills/devbooks-spec-contract/references//350/247/204/346/240/274/345/217/230/346/233/264/346/217/220/347/244/272/350/257/215.md +63 -0
- package/skills/devbooks-spec-contract/references//351/232/220/345/274/217/345/217/230/346/233/264/346/243/200/346/265/213/346/217/220/347/244/272/350/257/215.md +183 -0
- package/skills/devbooks-spec-contract/scripts/implicit-change-detect.sh +378 -0
- package/skills/devbooks-spec-gardener/SKILL.md +72 -0
- package/skills/devbooks-spec-gardener/references//350/247/204/346/240/274/345/233/255/344/270/201/346/217/220/347/244/272/350/257/215.md +41 -0
- package/skills/devbooks-test-owner/SKILL.md +172 -0
- package/skills/devbooks-test-owner/references//345/217/230/346/233/264/351/252/214/350/257/201/344/270/216/350/277/275/346/272/257/346/250/241/346/235/277.md +228 -0
- package/skills/devbooks-test-owner/references//345/274/202/346/255/245/347/263/273/347/273/237/346/265/213/350/257/225/347/255/226/347/225/245.md +316 -0
- package/skills/devbooks-test-owner/references//346/265/213/350/257/225/344/273/243/347/240/201/346/217/220/347/244/272/350/257/215.md +208 -0
- package/skills/devbooks-test-owner/references//346/265/213/350/257/225/345/210/206/345/261/202/347/255/226/347/225/245.md +281 -0
- package/skills/devbooks-test-owner/references//346/265/213/350/257/225/351/251/261/345/212/250.md +394 -0
- package/skills/devbooks-test-owner/references//350/247/243/344/276/235/350/265/226/346/212/200/346/234/257/351/200/237/346/237/245/350/241/250.md +432 -0
- package/skills/devbooks-test-reviewer/SKILL.md +189 -0
- package/templates/.devbooks/config.yaml +88 -0
- package/templates/claude-commands/devbooks/apply.md +38 -0
- package/templates/claude-commands/devbooks/archive.md +33 -0
- package/templates/claude-commands/devbooks/backport.md +19 -0
- package/templates/claude-commands/devbooks/bootstrap.md +19 -0
- package/templates/claude-commands/devbooks/c4.md +19 -0
- package/templates/claude-commands/devbooks/challenger.md +19 -0
- package/templates/claude-commands/devbooks/code.md +19 -0
- package/templates/claude-commands/devbooks/debate.md +19 -0
- package/templates/claude-commands/devbooks/delivery.md +19 -0
- package/templates/claude-commands/devbooks/design.md +19 -0
- package/templates/claude-commands/devbooks/entropy.md +19 -0
- package/templates/claude-commands/devbooks/federation.md +19 -0
- package/templates/claude-commands/devbooks/gardener.md +19 -0
- package/templates/claude-commands/devbooks/impact.md +19 -0
- package/templates/claude-commands/devbooks/index.md +19 -0
- package/templates/claude-commands/devbooks/judge.md +19 -0
- package/templates/claude-commands/devbooks/plan.md +19 -0
- package/templates/claude-commands/devbooks/proposal.md +19 -0
- package/templates/claude-commands/devbooks/quick.md +42 -0
- package/templates/claude-commands/devbooks/review.md +19 -0
- package/templates/claude-commands/devbooks/router.md +19 -0
- package/templates/claude-commands/devbooks/spec.md +19 -0
- package/templates/claude-commands/devbooks/test-review.md +19 -0
- package/templates/claude-commands/devbooks/test.md +19 -0
- package/templates/dev-playbooks/README.md +458 -0
- package/templates/dev-playbooks/changes/.gitkeep +1 -0
- package/templates/dev-playbooks/constitution.md +116 -0
- package/templates/dev-playbooks/project.md +96 -0
- package/templates/dev-playbooks/scripts/.gitkeep +1 -0
- package/templates/dev-playbooks/specs/_meta/anti-patterns/.gitkeep +2 -0
- package/templates/dev-playbooks/specs/_meta/glossary.md +47 -0
- package/templates/dev-playbooks/specs/_meta/project-profile.md +79 -0
- package/templates/dev-playbooks/specs/architecture/fitness-rules.md +95 -0
package/skills/devbooks-test-owner/references//346/265/213/350/257/225/351/251/261/345/212/250.md
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# 自动化架构治理与AI驱动重构:全AI编码环境下的验证策略与企业级最佳实践
|
|
2
|
+
|
|
3
|
+
## 摘要
|
|
4
|
+
|
|
5
|
+
随着大语言模型(LLM)能力的提升,软件开发范式正经历从“人写代码”向“AI生成、人审查”甚至“全AI编码(All-AI Coding)”的深刻转型。然而,在处理复杂的架构级重构任务时,全AI编码模式面临着严重的可靠性挑战,最典型的表现即为“递归修复循环(Recursive Repair Loop)”:AI生成的修复方案由AI审查,审查发现新错误,修复后再次审查发现更多错误,导致代码质量震荡且无法收敛。这一现象揭示了当前基于概率生成的“AI审查”在缺乏确定性锚点(Deterministic Ground Truth)时的本质局限。
|
|
6
|
+
|
|
7
|
+
本报告旨在深入探讨这一技术瓶颈,并针对无法进行人工代码审查的开发环境,提出一套基于“架构即代码(Architecture-as-Code)”与“测试驱动重构(Test-Driven Refactoring)”的企业级解决方案。报告首先从理论层面剖析了LLM在自我纠错与递归推理中的病理特征,论证了为何单纯依赖AI审查在架构层面是不可行的。随后,详细阐述了如何利用ArchUnit、NetArchTest等工具构建可执行的架构适应性函数(Fitness Functions),以数学确定的方式验证修复计划的完整性。最后,结合Cursor、Aider、SonarQube等前沿工具,构建了一套无需人工介入代码细节的自动化治理流水线,为全AI编码时代的软件质量保障提供了系统的实施路径。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. 递归修复循环的病理学分析:为何AI无法审查AI
|
|
12
|
+
|
|
13
|
+
在全AI编码的工作流中,用户遇到的核心痛点是“修复->审查->再修复”的无限循环。要解决这一问题,必须首先理解导致这一现象的认知科学与计算语言学机制。这并非单纯的提示词工程(Prompt Engineering)问题,而是概率模型在封闭闭环中缺乏外部反馈信号时的必然系统性失效。
|
|
14
|
+
|
|
15
|
+
### 1.1 概率验证与幻觉放大
|
|
16
|
+
|
|
17
|
+
传统的代码审查依赖于人类专家的心智模型,该模型建立在逻辑推理、领域知识与运行时行为的确定性理解之上。相比之下,LLM的“审查”本质上是基于训练数据的**下一个Token预测** 1。
|
|
18
|
+
|
|
19
|
+
当AI被要求“审查”代码时,它并非在构建代码的抽象语法树(AST)或模拟执行路径,而是在模拟“代码审查员”的语言模式。在训练语料(如GitHub Pull Requests)中,审查意见通常包含批评与修改建议。因此,模型存在一种统计学上的**批评偏置(Critique Bias)**:为了扮演好“审查员”的角色,它倾向于找出问题,即使代码在功能上是正确的。这种倾向导致了“幻觉错误(Hallucinated Bugs)”的产生,例如声称某个已导入的变量未定义,或将风格偏好误判为逻辑缺陷 3。
|
|
20
|
+
|
|
21
|
+
在递归循环中,第一轮审查产生的幻觉错误会被第二轮修复Agent视为必须解决的真实需求,从而修改原本正确的代码。这种修改往往破坏了原有的逻辑结构,导致第三轮审查发现真实的回归错误。如此往复,代码熵值(Entropy)不断增加,而非降低。
|
|
22
|
+
|
|
23
|
+
### 1.2 谄媚效应(Sycophancy)与上下文坍塌
|
|
24
|
+
|
|
25
|
+
研究表明,LLM表现出显著的**谄媚行为(Sycophancy)**,即倾向于顺从用户的隐含偏见或上下文中的既定前提 4。
|
|
26
|
+
|
|
27
|
+
- **回归性谄媚(Regressive Sycophancy):** 当用户或前序Agent指出“这里有错误”时,当前的AI模型即使面对正确的代码,也会倾向于承认错误并尝试“修复”。这种对错误前提的顺从是导致修复循环无法收敛的关键心理动力学因素 4。
|
|
28
|
+
|
|
29
|
+
- **上下文坍塌(Context Collapse):** 架构重构涉及全局依赖关系。然而,LLM受限于上下文窗口,往往只能关注当前编辑的文件片段。在“修复文件A”时,AI可能遗忘了该修改破坏了“文件B”中的契约。当审查Agent查看文件B时,发现契约破坏,要求修复,这又反过来破坏了文件A。这种由于缺乏全局一致性视图导致的局部最优解震荡,是大型重构任务失败的主要原因 3。
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### 1.3 内在自我纠错的局限性
|
|
33
|
+
|
|
34
|
+
尽管业界对AI的自我反思(Self-Reflection)寄予厚望,但实证研究显示,在缺乏外部工具(如编译器、解释器、测试结果)辅助的情况下,LLM的**内在自我纠错(Intrinsic Self-Correction)**能力极其有限,甚至可能导致性能退化 7。
|
|
35
|
+
|
|
36
|
+
|**特征**|**人类审查**|**AI审查 (LLM)**|
|
|
37
|
+
|---|---|---|
|
|
38
|
+
|**验证机制**|逻辑推理 + 经验判断|模式匹配 + 概率预测|
|
|
39
|
+
|**错误识别**|基于因果关系|基于文本统计特征|
|
|
40
|
+
|**上下文感知**|全局/系统级|局部/窗口受限|
|
|
41
|
+
|**对批评的反应**|辩证分析|倾向顺从 (谄媚)|
|
|
42
|
+
|**结果稳定性**|高|低 (随机性)|
|
|
43
|
+
|
|
44
|
+
**结论:** 在架构治理中,使用概率性的AI去验证概率性的AI产出,在数学上是无法收敛的。必须引入**确定性锚点(Deterministic Anchors)**——即编译器错误、测试失败、静态分析报告——来打破这一循环。
|
|
45
|
+
|
|
46
|
+
### 1.4 避免“同源谬误”的输入原则
|
|
47
|
+
|
|
48
|
+
在多Agent协作的全AI开发流中,最危险的闭环是“根据实施计划生成测试,再根据相同的计划生成代码”。如果测试与代码共享同一输入文档,验证环路便完全失效。为此,System Prompt 必须引导各Agent遵守以下“真理来源”隔离策略:
|
|
49
|
+
|
|
50
|
+
- **测试生成源(Verifier Input):** 仅允许基于《架构设计文档》或《需求规格说明书》提取验收标准,生成ArchUnit规则与集成测试。测试Agent严禁参考任何详细的实施计划(Plan),以保持“甲方验收”视角的独立性。
|
|
51
|
+
- **代码生成源(Coder Input):** 仅参考《实施计划文档》、实时测试报错以及源码本身。实现细节应向测试反馈靠拢,而不是反向影响测试。
|
|
52
|
+
- **冲突解决准则:** 当实现与测试发生冲突时,以设计文档驱动的测试为“黄金真理(Golden Truth)”。实现必须向测试描述的设计意图妥协,而非修改测试以迁就实现。
|
|
53
|
+
|
|
54
|
+
通过在System Prompt中强化上述1.4章节,可以在不增加人工参与的情况下确保“测试-实现”形成真正的正交验证,而非自证循环。
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 2. 架构与行为的双重锚点(Architecture & Behavior Anchors)
|
|
59
|
+
|
|
60
|
+
针对用户提出的第一个核心问题:**“是否可以通过编写完整的测试套件来检查修复计划是否完成?”**
|
|
61
|
+
|
|
62
|
+
答案是**肯定的**。但这里的“测试套件”并非传统的单元测试(Unit Tests),而是**架构适应性函数(Architectural Fitness Functions)**。这是一种将架构规则编码为可执行测试的技术,能够以数学精度验证系统结构是否符合预期的设计蓝图。
|
|
63
|
+
|
|
64
|
+
### 2.1 结构锚点:架构适应性函数(ArchUnit)
|
|
65
|
+
|
|
66
|
+
架构适应性函数源自演进式架构(Evolutionary Architecture)理论,旨在度量系统架构与预设目标的契合度 9。在全AI编码环境中,它们充当了“自动化架构师”的角色,不仅验证功能,更验证结构。
|
|
67
|
+
|
|
68
|
+
主要工具生态包括:
|
|
69
|
+
|
|
70
|
+
- **ArchUnit (Java):** 行业标准工具,通过分析Java字节码来验证包依赖、类继承、注解使用等规则。它不依赖源码文本,因此对AI生成的格式错误具有鲁棒性 11。
|
|
71
|
+
|
|
72
|
+
- **NetArchTest (.NET):** 专为.NET生态设计的流式API,用于强制执行分层架构和依赖规则 14。
|
|
73
|
+
|
|
74
|
+
- **Dependency-Cruiser / TsArch (JavaScript/TypeScript):** 针对前端及Node.js环境,通过解析抽象语法树(AST)来验证模块间的依赖图谱 17。
|
|
75
|
+
|
|
76
|
+
- **ArchUnitNET:** ArchUnit的.NET移植版,提供跨语言的架构治理能力 18。
|
|
77
|
+
|
|
78
|
+
**SaaS 升级专项规则:** 在多租户环境中,结构锚点必须进一步包含RLS(Row-Level Security)策略、租户注解(如 `@TenantAware`)以及跨域隔离边界的检测。通过在ArchUnit/NetArchTest中添加“所有访问 `tenant_data` 的仓储都需要 `@TenantAware` 注解”、“共享服务禁止直接引用租户专属 schema”等规则,可在升级过程中强制验证租户隔离未被破坏。
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
### 2.2 行为锚点:黑盒契约测试(Contract Tests)
|
|
82
|
+
|
|
83
|
+
结构正确不代表外部行为可信。为扩展“确定性锚点”的范围,测试Agent必须把设计文档中的API定义、数据流和副作用转写为契约级集成测试:
|
|
84
|
+
|
|
85
|
+
- **只看契约,不看实现:** 测试逻辑仅依据《架构设计文档》或《需求规格说明书》。它不依赖类名、方法名等Plan细节,从而允许代码实现自由演进。
|
|
86
|
+
- **以HTTP/消息驱动验证:** 通过真实的接口调用触发系统,校验HTTP状态码、Response Body以及数据库关键表(如 `audit_logs`、`tenant_events`)中的记录变化。
|
|
87
|
+
- **副作用可观测:** 对审计日志、事件总线、RLS策略等外部副作用建立断言,确保“tenant_id被写入”、“审计记录落地”这些行为与设计契约一致。
|
|
88
|
+
- **示例:** `POST /impersonate` 必须在数据库插入一条 `IMPERSONATE_START` 记录,无论后台使用 `ServiceA` 还是 `ServiceB`。
|
|
89
|
+
|
|
90
|
+
只有当行为锚点的黑盒契约测试与结构锚点的ArchUnit规则同时通过,才能确认“外部行为正确 + 内部结构正确”这对双重锚点均被满足。
|
|
91
|
+
|
|
92
|
+
### 2.3 将修复计划转化为可执行的验收标准
|
|
93
|
+
|
|
94
|
+
在传统的开发模式中,架构修复计划通常是一份文档(如“将订单服务与库存数据库解耦”)。在全AI模式下,这份文档必须被转化为**架构测试代码**。
|
|
95
|
+
|
|
96
|
+
**操作流程:**
|
|
97
|
+
|
|
98
|
+
1. **计划解析:** AI架构师Agent分析当前的架构缺陷(例如:循环依赖、分层违规)。
|
|
99
|
+
|
|
100
|
+
2. **规则生成:** 编写ArchUnit规则来描述“修复后的理想状态”。
|
|
101
|
+
|
|
102
|
+
- _缺陷描述:_ “UI层直接调用了数据层。”
|
|
103
|
+
|
|
104
|
+
- _ArchUnit规则:_`noClasses().that().resideIn("..ui..").should().dependOnClassesThat().resideIn("..data..")`
|
|
105
|
+
|
|
106
|
+
3. **红/绿循环:** 在修复开始前运行这些测试,它们应当**失败(Red)**。这种失败证明了测试准确地捕捉到了当前的架构缺陷。
|
|
107
|
+
|
|
108
|
+
4. **验证完成度:** 当且仅当这些测试全部**通过(Green)**时,修复计划才被视为在结构上已完成。
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
### 2.4 验证“完整性”的策略
|
|
112
|
+
|
|
113
|
+
用户担心“修复计划是否完成”。架构测试提供了比人工审查更严格的“完成”定义:
|
|
114
|
+
|
|
115
|
+
- **全量扫描:** 架构测试会对编译后的所有类进行扫描。如果修复计划遗漏了任何一个隐蔽的类文件(例如,AI修复了99个文件,漏掉了1个),ArchUnit会立即报错。人类在审查数百个文件时极易产生疲劳遗漏,而机器不会 19。
|
|
116
|
+
|
|
117
|
+
- **防止回归:** 一旦修复完成,这些测试将被保留在CI流水线中。如果未来的AI修改意外重新引入了旧的架构缺陷,构建将自动失败。这种机制被称为**架构棘轮(Architectural Ratchet)** 9。
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
**示例:分层架构验证代码 (Java/ArchUnit)**
|
|
121
|
+
|
|
122
|
+
Java
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
@ArchTest
|
|
126
|
+
public static final ArchRule layered_architecture_must_be_respected =
|
|
127
|
+
layeredArchitecture()
|
|
128
|
+
.consideringOnlyDependenciesInAnyPackage("com.myapp..")
|
|
129
|
+
.layer("Controller").definedBy("..controller..")
|
|
130
|
+
.layer("Service").definedBy("..service..")
|
|
131
|
+
.layer("Persistence").definedBy("..persistence..")
|
|
132
|
+
|
|
133
|
+
.whereLayer("Controller").mayNotBeAccessedByAnyLayer()
|
|
134
|
+
.whereLayer("Service").mayOnlyBeAccessedByLayers("Controller")
|
|
135
|
+
.whereLayer("Persistence").mayOnlyBeAccessedByLayers("Service");
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
此代码段定义了一个严格的单向依赖规则。如果AI生成的代码中存在Service反向调用Controller,或Controller跳过Service直接调用Persistence的情况,测试将直接失败。这为“修复是否完成”提供了一个二元(Binary)、无歧义的判断标准。
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## 3. 企业级最佳实践:无人值守的治理流水线
|
|
143
|
+
|
|
144
|
+
针对用户提出的第二个问题:**“企业级的最佳实践是什么(在无法人肉看代码的情况下)?”**
|
|
145
|
+
|
|
146
|
+
在无法进行人工代码审查的约束下,企业级治理的核心理念必须从**“基于观察的信任(Trust by Observation)”**转向**“基于约束的信任(Trust by Constraint)”**。这意味着我们需要构建一套自动化系统,使得AI Agent只有在满足一系列严格的机械检查后,其代码才能被合并。
|
|
147
|
+
|
|
148
|
+
这一体系由四个支柱构成:测试驱动重构(Test-Driven Refactoring)、遗留代码快照(Snapshot Testing)、静态分析门禁(Static Analysis Gates)以及Agent职能分离(Agentic Role Separation)。
|
|
149
|
+
|
|
150
|
+
### 3.1 核心工作流:测试驱动重构 (TDD) 的倒置应用
|
|
151
|
+
|
|
152
|
+
传统的TDD要求先写测试再写代码。在AI辅助重构中,这一流程至关重要,因为它解决了AI“不知道何时停止”的问题 20。
|
|
153
|
+
|
|
154
|
+
**实施步骤:**
|
|
155
|
+
|
|
156
|
+
1. **定义测试(Red):** 在AI开始修改业务逻辑之前,要求其先编写一个能够复现架构缺陷或描述新架构行为的测试。
|
|
157
|
+
|
|
158
|
+
- _指令示例:_ “编写一个ArchUnit测试,断言所有`OrderService`的依赖都必须来自`OrderDomain`包。运行它,确认它目前是失败的。”
|
|
159
|
+
|
|
160
|
+
2. **AI实现(Green):** 指令AI修改源代码,目标仅仅是**使测试通过**。
|
|
161
|
+
|
|
162
|
+
- _约束:_ AI不得修改测试代码本身(除非获得特殊授权)。
|
|
163
|
+
|
|
164
|
+
- _优势:_ 这消除了AI的“自由发挥”空间。测试报错信息(Compiler Error / Assertion Error)为AI提供了精确的、确定性的反馈,使其能够有效地进行自我修正,而无需依赖幻觉频发的“自我审查” 21。
|
|
165
|
+
|
|
166
|
+
3. **重构(Refactor):** 在测试通过的保护下,允许AI优化代码结构。
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
### 3.2 遗留系统安全网:快照测试 (Snapshot Testing)
|
|
170
|
+
|
|
171
|
+
对于许多遗留项目,编写细粒度的单元测试非常困难。此时,**快照测试**(或称黄金主版测试 Golden Master Testing)是企业级大规模重构的标配 24。
|
|
172
|
+
|
|
173
|
+
- **原理:** 不去理解代码的内部逻辑,而是捕获系统的“输入-输出”指纹。记录所有API接口、数据库状态、日志输出的当前状态,保存为“快照”。
|
|
174
|
+
|
|
175
|
+
- **AI角色:** AI非常擅长生成这种重复性的特征测试代码 27。
|
|
176
|
+
|
|
177
|
+
- **验证逻辑:** 在进行架构重构(如移动类、拆分包)时,只要业务逻辑未变,快照测试应当保持100%通过。如果快照失败,说明AI在重构过程中意外破坏了业务逻辑。
|
|
178
|
+
|
|
179
|
+
- **价值:** 这为“全AI编码者”提供了一个黑盒验证机制——即使我不看代码,只要快照没变且架构测试通过,我就能确信系统既完成了重构又没有引入回归错误 24。
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
### 3.3 Agent职能分离:架构师与工匠
|
|
183
|
+
|
|
184
|
+
在全AI环境中,避免使用同一个Chat Session完成所有任务。应当模拟人类团队的分工,构建多Agent协作体系 29。
|
|
185
|
+
|
|
186
|
+
|**Agent 角色**|**权限与职责**|**输入限制(关键)**|
|
|
187
|
+
|---|---|---|
|
|
188
|
+
|**验收工程师 (Verifier / QA)**|只读。将设计/需求文档翻译为ArchUnit规则、契约测试与快照基线。负责运行并解读测试结果。|只允许查看《架构设计文档》或《需求规格说明书》,严禁查看 Plan 文档和源码,以保持“甲方验收”视角。|
|
|
189
|
+
|**架构规划师 (Planner)**|只读。把设计文档转化为可执行的实施步骤(Plan.md),并列出需要触达的代码模块。|可查看《设计文档》和既有代码库,但不得访问Verifier生成的测试内容,以免“先看到答案”。|
|
|
190
|
+
|**开发工匠 (Coder)**|读写。根据Plan实现代码并迭代直至通过所有Verifier测试;可修改源码与配置。|只能参考《计划文档》、测试报错和源码。禁止直接查看设计文档原文,防止实现与测试同源。|
|
|
191
|
+
|
|
192
|
+
这种分离打破了单体Agent的“上下文污染”,确保了架构指令的纯洁性。
|
|
193
|
+
|
|
194
|
+
### 3.4 静态分析作为“冷酷警察”
|
|
195
|
+
|
|
196
|
+
由于没有人类进行Code Review,必须引入比人类更严格的**静态应用安全测试(SAST)**工具 32。
|
|
197
|
+
|
|
198
|
+
- **工具推荐:** SonarQube(配置Quality Gate)、Codacy、Qodo。
|
|
199
|
+
|
|
200
|
+
- **策略:** 设置“零容忍”策略。如果SonarQube发现任何新的Code Smell、Bug或安全漏洞,CI流水线直接失败。
|
|
201
|
+
|
|
202
|
+
- **闭环:** 将SonarQube的JSON格式报告直接喂给AI Agent。相比于模糊的自然语言反馈,AI对行号明确、错误类型标准的SAST报告具有极高的修复成功率 34。
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 4. 实战落地:构建“无代码审查”开发环境
|
|
208
|
+
|
|
209
|
+
针对用户的“全AI编码”场景,以下推荐具体的工具链配置与工作流脚本。这是目前业界最先进的**“Agentic IDE”**配置方案。
|
|
210
|
+
|
|
211
|
+
### 4.1 工具栈选择
|
|
212
|
+
|
|
213
|
+
1. **IDE/Agent:** **Cursor** (配合 Composer 功能) 或 **Windsurf**。它们具备多文件编辑和上下文感知能力。
|
|
214
|
+
|
|
215
|
+
2. **CLI 自动化:** **Aider**。Aider在“测试驱动循环”方面表现卓越,支持自动运行测试并根据报错修复 35。
|
|
216
|
+
|
|
217
|
+
3. **架构守护:** **ArchUnit** (Java) / **NetArchTest** (.NET)。
|
|
218
|
+
|
|
219
|
+
4. **质量门禁:** **SonarQube Cloud** (免费版支持开源项目) 或本地 **ESLint/Pylint** (配置严格规则)。
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
### 4.2 配置 Cursor Rules (`.cursor/rules`)
|
|
223
|
+
|
|
224
|
+
在项目根目录创建 `.cursor/rules` 文件,将架构约束注入到每一次AI交互中。这相当于给AI戴上了“紧箍咒” 36。
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## description: 架构重构与质量红线 globs: **/_.java, **/_.cs, **/*.ts alwaysApply: true
|
|
229
|
+
|
|
230
|
+
# 核心原则
|
|
231
|
+
|
|
232
|
+
1. **测试优先:** 在修改任何业务代码前,必须先运行 `./gradlew test` (或相应命令)。如果测试失败,优先修复测试。
|
|
233
|
+
|
|
234
|
+
2. **架构约束:**
|
|
235
|
+
|
|
236
|
+
- 禁止在 Controller 层直接调用 Repository 层。
|
|
237
|
+
|
|
238
|
+
- 禁止引入循环依赖。
|
|
239
|
+
|
|
240
|
+
- 任何架构变更必须通过 `ArchitectureTest.java` 的验证。
|
|
241
|
+
|
|
242
|
+
3. **禁止行为:**
|
|
243
|
+
|
|
244
|
+
- 禁止删除现有的测试用例来通过构建。
|
|
245
|
+
|
|
246
|
+
- 禁止使用 `System.out.println` 进行调试,必须使用日志框架。
|
|
247
|
+
|
|
248
|
+
4. **完成定义:**
|
|
249
|
+
|
|
250
|
+
- 只有当所有单元测试、架构测试及静态分析检查(Lint)全部通过时,任务才算完成。
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
### 4.3 Aider 的自动修复循环配置
|
|
254
|
+
|
|
255
|
+
对于大规模重构,建议使用 CLI 工具 Aider,因为它能实现真正的无人值守循环。
|
|
256
|
+
|
|
257
|
+
**启动命令示例:**
|
|
258
|
+
|
|
259
|
+
Bash
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
aider --model sonnet --architect --test-cmd "mvn test && mvn verify"
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**工作流解析:**
|
|
266
|
+
|
|
267
|
+
1. **--architect:** 启用架构师模式,Aider会先思考方案,再生成代码,减少盲目试错 31。
|
|
268
|
+
|
|
269
|
+
2. **--test-cmd:** 这是关键。每次Aider修改代码后,会自动运行Maven测试。
|
|
270
|
+
|
|
271
|
+
- 如果测试失败,Aider会自动捕获错误日志。
|
|
272
|
+
|
|
273
|
+
- Aider分析错误,并在无需人类干预的情况下尝试新一轮修复。
|
|
274
|
+
|
|
275
|
+
- 这个循环会一直持续直到测试通过或达到最大重试次数。
|
|
276
|
+
|
|
277
|
+
3. **效果:** 这直接替代了用户当前的“AI修复->AI审查”循环,将其替换为“AI修复->测试验证”的确定性循环 38。
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## 5. 局限性与风险提示
|
|
283
|
+
|
|
284
|
+
虽然上述方案能显著降低风险,但在“全AI编码”模式下仍需警惕以下盲点:
|
|
285
|
+
|
|
286
|
+
1. **测试本身的正确性:** 如果AI生成的测试本身就是错误的(例如:断言`1=1`的虚假测试),那么整个验证体系将失效。
|
|
287
|
+
|
|
288
|
+
- _对策:_ 使用**变异测试(Mutation Testing)**工具(如Pitest)。它会故意修改业务代码(引入Bug),看测试是否能检测出来。如果测试仍然通过,说明测试质量低。可以让AI分析变异测试报告来增强测试集。
|
|
289
|
+
|
|
290
|
+
2. **需求理解偏差:** 架构测试保证了“结构正确”,但不保证“业务正确”。
|
|
291
|
+
|
|
292
|
+
- _对策:_ 保持高层级的验收测试(Acceptance Tests)或端到端测试(E2E)的人工审核,或者至少由人工确认需求文档与测试用例描述的一致性。
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## 6. 结论
|
|
298
|
+
|
|
299
|
+
用户陷入的“递归修复循环”并非偶发故障,而是全AI开发模式下缺乏**确定性反馈机制**的必然结果。解决之道不在于优化Prompt让AI“审查得更仔细”,而在于引入无法被AI“忽悠”的数学化验证工具。
|
|
300
|
+
|
|
301
|
+
**针对用户问题的最终建议:**
|
|
302
|
+
|
|
303
|
+
1. **立即停止使用AI进行“代码审查”。** 将算力资源投入到编写**架构测试(ArchUnit)**和**快照测试**上。
|
|
304
|
+
|
|
305
|
+
2. **构建“红绿循环”。** 要求AI必须先看到红色的测试失败,才能编写代码。
|
|
306
|
+
|
|
307
|
+
3. **拥抱工具化治理。** 利用 `.cursor/rules` 和 Aider 的 `--test-cmd` 功能,将“审查”动作转化为自动化的“测试运行”动作。
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
通过实施**架构即代码**与**测试驱动重构**,即便是非代码编写者,也能通过掌控“规则”与“测试”来有效地驾驭AI,完成复杂的企业级架构重构任务。这种从“代码编写者”到“规格定义者”的角色转变,正是AI时代软件工程的必然演进方向。
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
### 表 1:验证策略对比分析
|
|
315
|
+
|
|
316
|
+
|**验证维度**|**传统人工审查**|**AI 审查 (当前困境)**|**架构即代码 (推荐方案)**|
|
|
317
|
+
|---|---|---|---|
|
|
318
|
+
|**验证基准**|专家经验与直觉|概率模型 (Token预测)|**确定性规则 (Bytecode/AST)**|
|
|
319
|
+
|**反馈性质**|建议性、模糊|幻觉性、谄媚、不稳定|**二元性 (Pass/Fail)、精确**|
|
|
320
|
+
|**覆盖范围**|抽样检查 (易疲劳)|窗口受限 (易遗漏)|**全量扫描 (100% 代码库)**|
|
|
321
|
+
|**循环收敛性**|高|**不收敛 (无限循环)**|**高 (红->绿->重构)**|
|
|
322
|
+
|**适合场景**|核心逻辑、复杂算法|简单语法检查、注释生成|**架构依赖、分层治理、规范强制**|
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## 7. 遗留代码修改算法(Legacy Code Change Algorithm)
|
|
327
|
+
|
|
328
|
+
> 来源:《修改代码的艺术》(Working Effectively with Legacy Code) - Michael Feathers
|
|
329
|
+
|
|
330
|
+
在修改遗留代码时,Test Owner 必须遵循以下 5 步算法,确保"先有测试锚点,再改动代码":
|
|
331
|
+
|
|
332
|
+
### 7.1 五步流程
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
336
|
+
│ 1. 确定改动点 → 2. 找测试点 → 3. 解依赖 → 4. 写测试 → 5. 改动 │
|
|
337
|
+
│ (Change Point) (Test Point) (Break Deps) (Write Tests) (Change) │
|
|
338
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
| 步骤 | 动作 | 产出 | 失败时回退 |
|
|
342
|
+
|------|------|------|-----------|
|
|
343
|
+
| **1. 确定改动点** | 定位需要修改的代码位置 | 文件:行号列表 | - |
|
|
344
|
+
| **2. 找测试点** | 识别 Pinch Point(汇点)作为测试切入点 | PP-xxx 列表 | 若找不到,进入步骤 3 |
|
|
345
|
+
| **3. 解依赖** | 应用解依赖技术使代码可测试 | 接缝/Mock 点 | 参考《解依赖技术速查表》 |
|
|
346
|
+
| **4. 写测试** | 在测试点写表征测试,捕获当前行为 | tests/xxx_test.py | 必须先 Red 后 Green |
|
|
347
|
+
| **5. 改动** | 在测试保护下修改代码 | 代码变更 | 测试失败则回滚 |
|
|
348
|
+
|
|
349
|
+
### 7.2 Pinch Point 优先原则
|
|
350
|
+
|
|
351
|
+
**定义**:Pinch Point 是多个调用路径汇聚的节点,在此处写测试可以用最少的测试覆盖最多的路径。
|
|
352
|
+
|
|
353
|
+
**识别方法**:
|
|
354
|
+
1. 从改动点向外追踪调用链
|
|
355
|
+
2. 找到"多入一出"的汇聚点(被 ≥2 个调用方使用的函数/类)
|
|
356
|
+
3. 优先在 Pinch Point 写测试,而非为每条路径写测试
|
|
357
|
+
|
|
358
|
+
**示例**:
|
|
359
|
+
```
|
|
360
|
+
调用链分析:
|
|
361
|
+
ControllerA.handleRequest() ─┐
|
|
362
|
+
ControllerB.handleBatch() ──┼──→ OrderService.processOrder() ──→ Repository.save()
|
|
363
|
+
EventHandler.onOrderEvent() ─┘ ↑
|
|
364
|
+
[Pinch Point]
|
|
365
|
+
|
|
366
|
+
测试策略:
|
|
367
|
+
✗ 错误: 为 ControllerA/ControllerB/EventHandler 各写 1 个测试(共 3 个)
|
|
368
|
+
✓ 正确: 只在 OrderService.processOrder() 写 1 个测试(覆盖全部 3 条路径)
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### 7.3 Test Owner 检查清单
|
|
372
|
+
|
|
373
|
+
在开始为遗留代码写测试前,必须回答以下问题:
|
|
374
|
+
|
|
375
|
+
- [ ] 改动点在哪里?(文件:行号)
|
|
376
|
+
- [ ] Pinch Point 在哪里?(若无法识别,需要先解依赖)
|
|
377
|
+
- [ ] 当前代码是否可测试?(若否,需要哪种解依赖技术?)
|
|
378
|
+
- [ ] 表征测试是否捕获了当前行为?(先 Red 验证测试有效,再 Green)
|
|
379
|
+
- [ ] 测试数量是否 = Pinch Point 数量?(而非调用路径数量)
|
|
380
|
+
|
|
381
|
+
### 7.4 感知与分离技术
|
|
382
|
+
|
|
383
|
+
当代码"无法测试"时,通常是因为缺乏**感知(Sensing)**或**分离(Separation)**能力:
|
|
384
|
+
|
|
385
|
+
| 问题 | 症状 | 解决方案 |
|
|
386
|
+
|------|------|---------|
|
|
387
|
+
| **感知缺失** | 无法观察代码的执行结果(如:私有方法、无返回值、副作用在外部系统) | 提取接口、暴露测试钩子、依赖注入 |
|
|
388
|
+
| **分离缺失** | 无法隔离被测代码(如:硬编码依赖、全局状态、静态调用) | 参数化构造器、提取接口、Subclass and Override |
|
|
389
|
+
|
|
390
|
+
**核心原则**:
|
|
391
|
+
- 感知 = 让测试能"看到"代码执行了什么
|
|
392
|
+
- 分离 = 让测试能"控制"代码依赖什么
|
|
393
|
+
|
|
394
|
+
详细技术参考:`解依赖技术速查表.md`
|