关于 aif-fix
aif-fix 是用于修复代码库中具体问题的开发技能,支持直接修复或先制定计划。需要回归检查时,它遵循先复现、再修复并重跑同一检查的流程。
主要功能
- 01支持直接修复与计划优先模式
- 02修复前执行回归检查
- 03修复后重跑同一检查
- 04读取项目规则与现有修复计划
- 05可与 Handoff 状态同步
适用场景
- 01复现并修复已报告的缺陷
- 02执行现有修复计划
- 03为缺陷制定修复计划
MCP 相关
在手动会话中,若修复计划首行包含 Handoff 标注,技能会调用 handoff_sync_status 同步任务状态。Handoff 模式下则不调用 MCP 工具。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lee-to/ ai-factory --skill aif-fix安装后在 Claude Code 中输入/aif-fix确认已加载。
详细介绍
修复 - Bug 修复工作流
修复代码库中的特定 Bug 或问题。支持两种模式:立即修复或先制定计划。默认工作流是在需要回归检查时优先进行回归验证:复现问题,确认报告中的行为,实现修复,然后验证同一项检查通过。
工作流
规范的回归优先策略
回归检查是指能够证明所报告的 Bug 或验证预期行为的最小有效测试、命令、夹具、API 调用、浏览器场景、脚本,或有文档记录的手动/运行时复现步骤。
当 Bug 需要回归覆盖时,所有工作流路径(立即修复、先制定计划和执行现有计划)都遵循此策略:
- 确定能够复现问题或体现预期行为的最小回归检查。
- 实现修复前执行检查,并确认检查失败或复现了所报告的问题。
- 实施能够解决根本原因的最小修复。
- 重新运行完全相同的检查,并确认检查通过。
- 仅在此之后,才在实际可行时运行相关的现有检查,并在有帮助时建议扩大覆盖范围。
回退处理:
- 如果没有可用的自动化/可执行检查,请记录最精简的手动/运行时复现步骤,以及为何不存在可执行检查。如果能够重新运行,则将记录的复现步骤视为第 4 步的回归检查。
- 如果完全没有有用的回归检查,请在实现前记录原因。在
HANDOFF_MODE=1下,只有在调查发现了可安全修复的可能根本原因时才继续;否则,将任务报告为受阻/无法复现,并停止,不得更改实现代码。在手动模式下,询问是否继续进行可能的修复、调整复现步骤或进一步调查。 - 如果修复前的回归检查意外通过,则视为复现不匹配:记录命令/检查、输入、环境假设和观察到的结果。然后使用上文针对
HANDOFF_MODE=1或手动模式的回退处理方式。
不要在后续工作流章节重复或弱化此策略。后续步骤应引用本节,并仅补充局部执行细节。
步骤 0(预备):检测交接模式
确定交接模式、任务 ID 和跳过审查标志。如果调用方在提示词中显式传入了 HANDOFF_MODE、HANDOFF_TASK_ID 和 HANDOFF_SKIP_REVIEW,则使用这些值。否则,使用 Bash 工具:
Bash: printenv HANDOFF_MODE || true
Bash: printenv HANDOFF_TASK_ID || true
Bash: printenv HANDOFF_SKIP_REVIEW || true
然后检查 HANDOFF_MODE:
当 HANDOFF_MODE 为 1(自主交接 Agent)时
交接协调器已直接管理状态转换和数据库写入。不要调用 MCP 工具。改为:
- 不要提出交互式问题: 不要使用
AskUserQuestion。如果$ARGUMENTS包含--plan-first,则使用“先制定计划”模式。否则,默认使用“立即修复”模式。当 Bug 需要回归检查时,加入回归优先处理和日志记录。 - 计划注释(强制): 如果
HANDOFF_TASK_ID非空,则必须将 `` 插入为修复计划文件的第一行,置于标题之前。设置了 HANDOFF_TASK_ID 却遗漏此注释属于 Bug — 完成前请核实。 这适用于步骤 1.1(创建新计划)和任何计划重写。
当 HANDOFF_MODE 不为 1(手动 Claude Code 会话)时
交接同步在流程中内联处理 — 任务 ID 提取和触发 MCP 同步的说明见步骤 0.1(读取修复计划文件后)。同步节点如下:
- 先制定计划(步骤 1.1):
"planning"→"plan_ready"(保存后) - 立即修复(步骤 2→5):
"implementing"(步骤 2 开始时)→ 如果HANDOFF_SKIP_REVIEW=1则为"done",否则为"review"(步骤 5) - 执行现有计划(步骤 0.1→5):
"implementing"(步骤 0.1)→ 如果HANDOFF_SKIP_REVIEW=1则为"done",否则为"review"(步骤 5)
重要: 除 done 之外,每次调用 handoff_sync_status 都必须传入 paused: true。
创建新的 FIX_PLAN.md 时:如果没有现有注释且不存在交接上下文,则不要添加注释。
步骤 0:加载配置并解析路径
首先: 如果 .ai-factory/config.yaml 存在,请读取它以解析:
- 路径:
paths.description、paths.architecture、paths.rules_file、paths.rules、paths.research、paths.fix_plan和paths.patches;派生research_bundles_dir = <paths.research 的父目录>/research/ - 语言:
language.ui用于提示词和摘要,language.artifacts用于FIX_PLAN.md和补丁文件,language.technical_terms用于文件中面向读者的技术术语 - 规则:
rules.base以及所有命名的rules.<area>条目
如果 config.yaml 不存在,请使用默认值:
- DESCRIPTION.md:
.ai-factory/DESCRIPTION.md - ARCHITECTURE.md:
.ai-factory/ARCHITECTURE.md - RULES.md:
.ai-factory/RULES.md - rules/:
.ai-factory/rules/ - RESEARCH.md:
.ai-factory/RESEARCH.md - FIX_PLAN.md:
.ai-factory/FIX_PLAN.md - patches/:
.ai-factory/patches/ ui_language:enartifact_language:entechnical_terms_policy:keep
解析后的语言值:
ui_language = language.ui || "en"artifact_language = language.artifacts || language.ui || "en"technical_terms_policy = language.technical_terms || "keep"
如果 technical_terms_policy 不是 keep、translate 或 mixed 之一,则按 keep 处理。english 等旧版取值也按 keep 处理。
所有 AskUserQuestion 提示、进度更新、修复摘要、测试提示和后续步骤指引都必须使用 ui_language 编写。
生成的 FIX_PLAN.md 和 paths.patches 下的自我改进补丁文件都必须使用 artifact_language 编写。
模板和示例定义的是结构,而非固定的英文内容。如果 artifact_language 不是 en,请在保存前翻译面向读者的标题、标签、分析文本、修复清单条目、风险、防范说明和补丁正文。保留 Handoff 注释、Markdown 结构、复选框语法、路径、命令、配置键、代码标识符、程序包名称、API 名称、原始错误消息、代码片段、[FIX] 等日志前缀以及补丁标签,不作更改。请保持 ## Research Context、Source:、Active Summary、Updated: 和 SHA256: 原样不变,因为下游研究漂移检查会将它们作为兼容性标记解析。对其他面向读者的术语应用 technical_terms_policy。
步骤 0.1:检查是否存在修复计划
在解析配置后,首先检查已解析的修复计划路径(默认值:.ai-factory/FIX_PLAN.md)。
如果文件存在:
- 读取已解析的修复计划文件
- 如果修复计划包含
## Research Context,则将其中嵌入的副本视为已提交的需求快照。使用规范语法^(?:Source|Reference):\s+\x60([^\x60]+)\x60\s+\(解析第一行Source:/Reference:;对于较旧的纯路径行,回退使用^(?:Source|Reference):\s+(.+?)\s+\(。仅当这两种形式都无法确定可用路径时,才回退到已配置的paths.research。 - 如果解析出的源文件位于
research_bundles_dir中,则要求其同级INDEX.md恰好包含 ``,并在## Artifact Index中链接该RESEARCH.md;否则发出WARN [research-drift]。有效的同级 C4/ADR/依赖产物仅用于说明理由。 - 如果存在
SHA256:,则严格提取位于和之间的当前源文本,移除 HTML 注释块,保留行顺序和行首空白,删除每行末尾的空格,使用 LF 换行,并以一个换行符结尾。通过 stdin 使用shasum -a 256或sha256sum计算哈希;摘要具有权威性。仅当不存在SHA256:时,才将Updated:用作旧版回退方式。源文件缺失/无效或修订版本不匹配时,发出WARN [research-drift];除非用户明确要求重新设定基准,否则基于嵌入的 Research Context 执行。 - 立即检查第一行是否包含 ``:
- 如果找到且
HANDOFF_MODE不是1(手动会话):提取任务 ID。调用handoff_sync_status,参数为{ taskId: <extracted-id>, newStatus: "implementing", sourceTimestamp: "<current UTC time in ISO 8601 format>", direction: "aif_to_handoff", paused: true }。(状态为"implementing",因为我们正在执行现有计划,而不是创建计划。) - 如果找到且
HANDOFF_MODE为1:由 Handoff 协调器处理同步——无需操作。 - 如果未找到:没有关联的 Handoff 任务——本会话剩余部分跳过所有 MCP 同步。
- 如果找到且
- 告知用户:"Found existing fix plan. Executing fix based on the plan."
- 跳过步骤 1(问题收集/模式选择),但仍需运行步骤 0.2以加载上下文
- 然后继续执行步骤 2:调查代码库,并以该计划为指南
- 当此 Bug 需要回归检查时,即使现有计划未包含该策略,也要在更改实现代码之前遵循规范的回归优先策略
- 按顺序遵循计划,但保留规范顺序:首先确认问题,然后实现修复,最后重新运行相同的回归检查
- 在步骤 4 中完全应用并验证修复后,仅当已解析的修复计划文件位于默认修复计划路径
.ai-factory/FIX_PLAN.md时才将其删除:rm .ai-factory/FIX_PLAN.md - 如果修复计划来自自定义的
paths.fix_plan值、明确提供的自定义计划路径,或任何非默认修复计划位置,则不要删除它。保留该文件,并在最终摘要中说明已保留自定义修复计划。 - 继续执行步骤 5(补充测试覆盖)和步骤 6(补丁)
如果文件不存在且 $ARGUMENTS 为空:
- 告知用户:"No fix plan found and no problem description provided. Please either provide a bug description (
/aif-fix <description>) or create a fix plan first." - 停止。
如果文件不存在且已提供 $ARGUMENTS:
- 继续执行下方的步骤 0.2。
步骤 0.2:加载项目上下文和过往经验
然后: 如果 .ai-factory/DESCRIPTION.md 存在,则读取该文件(使用配置中的路径),以了解:
- 技术栈(语言、框架、数据库)
- 项目架构
- 编码约定
还要读取 .ai-factory/ARCHITECTURE.md(使用配置中的路径)、解析后的 RULES.md 路径,以及配置的规则层级(如果存在),避免进行违反项目结构或本地约定的修复。
读取 .ai-factory/skill-context/aif-fix/SKILL.md — 如果该文件存在,则必须读取。
此文件包含 /aif-evolve 根据补丁、代码库约定和技术栈分析积累的项目专属规则。这些规则针对当前项目进行了定制。
如何应用 skill-context 规则:
- 将其视为此技能通用说明的项目级覆盖规则
- 当 skill-context 规则与本 SKILL.md 中编写的通用规则冲突时,以 skill-context 规则为准(更具体的上下文优先——这与嵌套 CLAUDE.md 文件的原则相同)
- 如果不存在冲突,则同时应用两者:SKILL.md 中的通用规则 + skill-context 中的项目规则
- 即使 skill-context 规则看似与此技能的默认规则矛盾,也不要忽略它们——这些规则源于项目经验,说明默认规则并不足够
- 关键: skill-context 规则适用于此技能的所有输出,包括 FIX_PLAN.md 模板和补丁文件。步骤 1.1 中的 FIX_PLAN.md 模板是一个基础结构。如果 skill-context 规则规定“步骤必须包含 X”或“计划必须有章节 Y”,则必须相应扩展模板。生成违反 skill-context 规则的 FIX_PLAN.md 或补丁属于错误。
执行要求: 生成任何输出产物后,都要根据所有 skill-context 规则进行检查。如果有任何规则被违反,就必须先修正输出,再呈现给用户。
补丁回退方案(仅限 skill-context 缺失时使用):
- 如果
.ai-factory/skill-context/aif-fix/SKILL.md不存在,且解析后的 patches 目录存在:- 使用
Glob在<resolved patches dir>中查找*.md文件 - 按文件名的字典序升序排列补丁文件,然后选择最后 10 个(若不足 10 个,则选择全部)
- 只读取所选的补丁文件
- 优先关注反复出现的根本原因和预防措施模式
- 使用
- 如果 skill-context 存在,默认情况下不要读取所有补丁。
- 仅当标签/文件与当前错误明显匹配时,才可选择检查少量近期补丁
步骤 1:理解问题并选择模式
从 $ARGUMENTS 中识别:
- 错误消息或异常行为
- 问题发生的位置(文件、函数、端点)
- 复现步骤(如果提供)
如果不清楚,请询问:
To fix this effectively, I need more context:
1. What is the expected behavior?
2. What actually happens?
3. Can you share the error message/stack trace?
4. When did this start happening?
理解问题后,使用 AskUserQuestion 询问用户选择一种模式:
问题:"How would you like to proceed with the fix?"
选项:
- 立即修复 — 立即调查并应用修复
- 先制定计划 — 创建修复计划供审查,之后再修复
根据选择:
- "先制定计划" → 继续执行步骤 1.1:创建修复计划
- "立即修复" → 跳过步骤 1.1,直接继续执行步骤 2:调查代码库
步骤 1.1:制定修复计划
Handoff 同步(仅手动模式): 如果已知 Handoff 任务 ID(来自 HANDOFF_TASK_ID 或现有注释),且 HANDOFF_MODE 不为 1,则调用 handoff_sync_status,并传入 { taskId: <id>, newStatus: "planning", sourceTimestamp: "<current UTC time in ISO 8601 format>", direction: "aif_to_handoff", paused: true }。
充分调查代码库,以理解问题并制定计划。
采用与步骤 2 相同的并行探索方式——同时启动 Explore Agent,调查问题区域、相关代码和以往模式。
如果解析出的研究路径存在,请在制定修复计划前先阅读。还要检查 research_bundles_dir 下的直接子级捆绑包,但只有当 INDEX.md 中恰好包含 一次、声明 `Status: active`,且在 `## Artifact Index` 中链接其 `RESEARCH.md` 时,才将其识别为活动项。最多选择一个与 Bug 明确相关的来源:优先选择明确的具体路径,其次是精确 slug、规范化后的 `Topic:` 或唯一的语义匹配,最后才考虑相关的旧文件;绝不根据新近程度选择。当选定的 Active Summary 影响计划修复时,将其复制到 `## Research Context`,并加入Source: <selected research path> (Active Summary, Updated: , SHA256: )``。如果研究内容不相关,则省略此部分。
在修复计划中添加 ## Research Context 时,使用与漂移检查相同的规范化算法计算摘要。无需创建临时仓库文件:通过标准输入或内联 shell 输入,将规范化文本传递给 shasum -a 256;如果不可用,则使用 sha256sum。将输出的第一个字段用作 SHA256:。
Agent 返回后,综合调查结果,以便:
- 确定根本原因(或最可能的原因)
- 梳理受影响的文件和函数
- 评估影响范围
然后创建解析后的修复计划文件(默认为 .ai-factory/FIX_PLAN.md)。
使用 artifact_language 编写修复计划。以下模板仅规定必需的结构;当 artifact_language 不是 en 时,保存前请翻译人类可读的标题、标签和说明文字,同时保留步骤 0 中的稳定技术标记。
写入前: 如果 HANDOFF_MODE 为 1 且 HANDOFF_TASK_ID 非空,文件的第一行必须为 ``,后接一个空行,然后是下面的计划内容。如果处于手动模式,且从现有注释中提取了任务 ID,则保留该 ID。
结构:
# Fix Plan: [Brief title]
**Problem:** [What's broken — from user's description]
**Created:** YYYY-MM-DD HH:mm
## Analysis
What was found during investigation:
- Root cause (or suspected root cause)
- Affected files and functions
- Impact scope
## Fix Checklist
Checklist entries for implementing the fix:
1. [ ] Apply the Canonical Regression-First Policy: add or identify the minimal regression check, or record why no useful check exists
2. [ ] Run the regression check and confirm it reproduces the reported problem, or record the fallback outcome from the policy
3. [ ] Implement the smallest fix for the root cause
4. [ ] Rerun the same regression check and confirm it passes when a rerunnable check exists
5. [ ] Run the closest related existing checks when practical
## Files to Modify
- `path/to/file.ts` — what changes are needed
- `path/to/another.ts` — what changes are needed
## Risks & Considerations
- Potential side effects
- Things to verify after the fix
- Edge cases to watch for
## Test Coverage
- Minimal regression check to confirm the bug before implementation
- Command/check to run before and after the fix
- Additional edge cases worth covering after the regression check passes
## Research Context (optional)
Include only when this fix plan is based on `RESEARCH.md`.
Source: `<selected research path>` (Active Summary, Updated: YYYY-MM-DD HH:MM, SHA256: <active-summary-sha256>)
填写 SHA256: 时,使用步骤 1.1 中的规范化和标准输入哈希规则。
创建计划后,输出:
## Fix Plan Created ✅
Plan saved to the resolved fix plan path.
Review the plan and when you're ready to execute, run:
/aif-fix
Handoff 同步(仅手动模式): 如果已知 Handoff 任务 ID 且 HANDOFF_MODE 不为 1,则调用 handoff_push_plan,并传入 { taskId: <id>, planContent: <full fix plan text> };随后调用 handoff_sync_status,并传入 { taskId: <id>, newStatus: "plan_ready", sourceTimestamp: "<current UTC time in ISO 8601 format>", direction: "aif_to_handoff", paused: true }。
在此处停止。不要应用修复。
步骤 2:调查代码库
Handoff 同步(仅手动模式的“立即修复”路径): 如果已知 Handoff 任务 ID 且 HANDOFF_MODE 不为 1,则调用 handoff_sync_status,并传入 { taskId: <id>, newStatus: "implementing", sourceTimestamp: "<current UTC time in ISO 8601 format>", direction: "aif_to_handoff", paused: true }。
使用 Task 工具并设置 subagent_type: Explore,并行调查问题。 这样可以保持主上下文简洁,并同时调查多个方向。
同时启动 2–3 个 Explore Agent:
Agent 1 — Locate the problem area:
Task(subagent_type: Explore, model: sonnet, prompt:
"Find code related to [error location / affected functionality].
Read the relevant functions, trace the data flow.
Thoroughness: medium.")
Agent 2 — Related code & side effects:
Task(subagent_type: Explore, model: sonnet, prompt:
"Find all callers/consumers of [affected function/module].
Identify what else might break or be affected.
Thoroughness: medium.")
Agent 3 — Similar past patterns (if patches exist):
Task(subagent_type: Explore, model: sonnet, prompt:
"Search for similar error patterns or related fixes in the codebase.
Check git log for recent changes to [affected files].
Thoroughness: quick.")
Agent 返回后,综合调查结果以确定:
- 根本原因(而不只是表面症状)
- 可能受影响的相关代码
- 现有错误处理
回退方案: 如果 Task 工具不可用,请直接调查:
- 使用 Glob/Grep 查找相关文件
- 阅读问题附近的代码
- 跟踪数据流
- 检查其他位置的类似模式
步骤 2.5:记录回归检查
在更改实现代码之前,先应用规范的回归优先策略。对于行为错误、解析/验证错误、API/数据错误、崩溃和回归问题,优先进行回归检查。如果更改属于非错误清理、纯静态修正或仅调查类请求,请记录该策略为何不适用,然后继续常规修复流程。
**防止投机取巧规则:**不要根据计划编写的实现来定制测试。测试必须描述外部预期行为或报告的问题条件。如果在进行任何修复之前测试就通过了,则可能是复现方式有误、问题已过时或环境不同;在更改实现代码之前,应按照规范的回归优先策略中的备用处理方式解决这一差异。
在工作笔记中记录选定的回归检查、修复前的结果以及任何备用处理决定,以便步骤 4 能够在修复后重新运行或复查同一检查。
步骤 3:实施修复
通过日志记录应用修复:
// ✅ REQUIRED: Add logging around the fix
console.log("[FIX] Processing user input", { userId, input });
try {
// The actual fix
const result = fixedLogic(input);
console.log("[FIX] Success", { userId, result });
return result;
} catch (error) {
console.error("[FIX] Error in fixedLogic", {
userId,
input,
error: error.message,
stack: error.stack,
});
throw error;
}
必须记录日志,原因如下:
- 用户需要验证修复是否有效
- 如果修复无效,日志有助于进一步调试
- 形成反馈闭环:用户提供日志 → 我们迭代
步骤 4:验证修复
- 检查代码能否编译/运行
- 如果步骤 2.5 创建、识别或记录了回归检查,则重新运行或复查同一检查,并确认修复后的行为
- 验证逻辑正确
- 确保没有引入回归问题
- 条件允许时,在回归检查通过后运行最相关的现有测试套件
步骤 5:建议补充测试覆盖
**交接同步(仅手动模式——当 HANDOFF_MODE 为 1 时完全跳过):**如果已知 Handoff 任务 ID,且 HANDOFF_MODE 不为 1:
- 使用
{ taskId: <id>, planContent: <fix summary or updated plan> }调用handoff_push_plan。 - 如果
HANDOFF_SKIP_REVIEW为1:使用{ taskId: <id>, newStatus: "done", sourceTimestamp: "<current UTC time in ISO 8601 format>", direction: "aif_to_handoff", paused: false }调用handoff_sync_status。 - 否则:使用
{ taskId: <id>, newStatus: "review", sourceTimestamp: "<current UTC time in ISO 8601 format>", direction: "aif_to_handoff", paused: true }调用handoff_sync_status。
始终建议补充测试覆盖:
步骤 5 和修复后的输出模板仅用于定义结构。请将面向用户的这些回复中的所有可读文本以 ui_language 呈现。代码片段、命令、文件路径、行引用、[FIX] 等日志前缀以及 AskUserQuestion 选项结构保持不变。
## Fix Applied ✅
The issue was: [brief explanation]
Fixed by: [what was changed]
### Logging Added
The fix includes logging with prefix `[FIX]`.
Please test and share any logs if issues persist.
### Recommended: Add More Test Coverage
If a regression check was created or identified in Step 2.5, this bug is now covered. Consider adding broader coverage to prevent nearby regressions:
\`\`\`typescript
describe('functionName', () => {
it('should handle [the edge case that caused the bug]', () => {
// Arrange
const input = /* the problematic input */;
// Act
const result = functionName(input);
// Assert
expect(result).toBe(/* expected */);
});
});
\`\`\`
AskUserQuestion: Would you like me to create the additional test coverage?
Options:
1. Yes, create the test
2. No, skip for now
处理用户的回复:
-
如果用户选择“是,创建测试”:
- 在适当的测试目录中创建测试文件(遵循项目惯例)
- 添加建议的补充测试用例及相关边缘情况
- 运行测试以验证其通过
- 然后继续步骤 6:创建自我改进补丁
-
如果用户选择“否,暂时跳过”:
- 直接继续步骤 6:创建自我改进补丁
日志记录要求
所有修复都必须包含日志记录:
- **日志前缀:**使用
[FIX]或[FIX:<issue-id>],便于筛选 - **记录输入:**记录正在处理的数据
- **记录成功:**确认修复有效
- **记录错误:**发生故障时提供完整上下文
- **可配置:**如果可用,使用 LOG_LEVEL
// Pattern for fixes
const LOG_FIX = process.env.LOG_LEVEL === "debug" || process.env.DEBUG_FIX;
function fixedFunction(input) {
if (LOG_FIX) console.log("[FIX] Input:", input);
// ... fix logic ...
if (LOG_FIX) console.log("[FIX] Output:", result);
return result;
}
示例
示例 1:空引用错误
用户: /aif-fix TypeError: Cannot read property 'name' of undefined in UserProfile
操作:
- 搜索 UserProfile 组件/函数
- 找到访问
.name的位置 - 针对用户为空的情况添加回归检查,并确认检查失败
- 添加空值检查并记录日志
- 重新运行同一回归检查,并确认检查通过
示例 2:API 返回错误数据
用户: /aif-fix /api/orders returns empty array for authenticated users
操作:
- 查找订单 API 端点
- 跟踪查询逻辑
- 查找错误(例如,筛选条件错误)
- 为已认证用户场景添加或找到集成回归检查,并确认检查失败
- 修复问题并添加日志
- 重新运行相同的回归检查,并确认检查通过
示例 3:表单验证不起作用
用户: /aif-fix email validation accepts invalid emails
操作:
- 查找邮箱验证逻辑
- 检查正则表达式或验证库的用法
- 为无效邮箱场景添加单元回归测试,并确认测试失败
- 修复验证逻辑
- 为验证失败添加日志
- 重新运行相同的回归测试,并确认测试通过
重要规则
- 先检查修复计划 - 先检查解析后的修复计划路径,再进行其他操作
- 计划模式 = 仅制定计划 - 用户选择“先制定计划”时,创建计划并停止。不要修复问题。
- 执行模式 = 遵循计划 - 解析后的修复计划存在时,逐步遵循计划执行。仅当该文件是默认的
.ai-factory/FIX_PLAN.md时,才在确认执行成功后删除;保留自定义或非默认修复计划文件。 - 不写报告 - 不要创建总结文档(补丁是学习产物,不是报告)
- 始终记录日志 - 每项修复都必须添加日志以便反馈
- 需要检查时先做回归检查 - 如果错误需要回归覆盖,在更改实现代码之前遵循规范的回归优先策略;在问题可复现时确认问题,然后在修复后验证相同的回归检查
- 不要让测试迎合实现 - 回归测试应体现报告中的行为或预期行为,而不是内部实现形式
- 始终建议额外测试 - 除必要的回归检查外,帮助防止附近功能出现回归
- 根本原因 - 修复实际问题,而非表面症状
- 最小改动 - 不要重构无关代码
- 一次修复一个问题 - 不要扩大范围
- 清理 - 修复成功执行后,删除解析后的修复计划文件
- 所有权边界 -
/aif-fix负责paths.fix_plan和paths.patches;除非用户明确提出要求,否则将.ai-factory/DESCRIPTION.md、路线图、规则和架构上下文产物视为只读 - 日志范围 - 修复必须遵循
[FIX]日志要求;此命令中的上下文门控输出应使用WARN/ERROR,且不得更改其他技能的全局日志策略
修复后
在步骤 5 中使用此输出模板(在询问是否需要额外测试的 AskUserQuestion 之前):
## Fix Applied ✅
**Issue:** [what was broken]
**Cause:** [why it was broken]
**Fix:** [what was changed]
**Regression check:** [command/check and result, manual/runtime reproduction result, or "not available: <reason>"]
**Files modified:**
- path/to/file.ts (line X)
**Logging added:** Yes, prefix `[FIX]`
步骤 6:创建自我改进补丁
每次修复后都必须创建补丁。 这会为未来的修复构建知识库。
创建补丁:
-
如果目录不存在,则创建目录:
mkdir -p <resolved patches dir> -
创建补丁文件,并使用当前时间戳作为文件名。 格式:
YYYY-MM-DD-HH.mm.md(例如,2026-02-07-14.30.md) -
使用此模板:
使用 artifact_language 编写补丁产物。下方模板仅规定必需的结构;当 artifact_language 不是 en 时,保存前请翻译人类可读的标题、标签、根本原因文本、解决方案文本和预防措施文本,同时保留步骤 0 中的稳定技术标记。
# [Brief title describing the fix]
**Date:** YYYY-MM-DD HH:mm
**Files:** list of modified files
**Severity:** low | medium | high | critical
## Problem
What was broken. How it manifested (error message, wrong behavior).
Be specific — include the actual error or symptom.
## Root Cause
WHY the problem occurred. This is the most valuable part.
Not "what was wrong" but "why it was wrong":
- Logic error? Why was the logic incorrect?
- Missing check? Why was it missing?
- Wrong assumption? What was assumed?
- Race condition? What sequence caused it?
## Solution
How the fix was implemented. Key code changes and reasoning.
Include the approach, not just "changed line X".
## Prevention
How to prevent this class of problems in the future:
- What pattern/practice should be followed?
- What should be checked during code review?
- What test would catch this?
## Tags
Space-separated tags for categorization, e.g.:
`#null-check` `#async` `#validation` `#typescript` `#api` `#database`
补丁示例:
# Null reference in UserProfile when user has no avatar
**Date:** 2026-02-07 14:30
**Files:** src/components/UserProfile.tsx
**Severity:** medium
## Problem
TypeError: Cannot read property 'url' of undefined when rendering
UserProfile for users without an uploaded avatar.
## Root Cause
The `user.avatar` field is optional in the database schema but the
component accessed `user.avatar.url` without a null check. This was
introduced in commit abc123 when avatar display was added — the
developer tested only with users that had avatars.
## Solution
Added optional chaining: `user.avatar?.url` with a fallback to a
default avatar URL. Also added a null check in the Avatar sub-component.
## Prevention
- Always check if database fields marked as `nullable` / `optional`
are handled with null checks in the UI layer
- Add test cases for "empty state" — user with minimal data
- Consider a lint rule for accessing nested optional properties
## Tags
`#null-check` `#react` `#optional-field` `#typescript`
这不是可选项。 每次修复都必须生成补丁。补丁就是你的学习成果。
上下文清理
如有需要,建议用户释放上下文空间:/clear(完全重置)或 /compact(压缩历史记录)。
请勿:
- ❌ 用户选择“先制定计划”时仍然应用修复——只能制定修复计划并停止
- ❌ 跳过开始时的修复计划检查
- ❌ 成功执行修复后仍保留默认的
.ai-factory/FIX_PLAN.md - ❌ 执行后删除自定义或非默认的修复计划文件
- ❌ 生成报告或摘要(补丁不是报告,而是学习材料)
- ❌ 重构无关代码
- ❌ 修复时添加功能
- ❌ 跳过日志记录
- ❌ 跳过测试建议
- ❌ 跳过补丁创建