Core rules
- Reproduce first, then find the cause: without a reproduction, do not draw conclusions or declare it fixed.
- Do not change product code during diagnosis: only add reproduction tests and temporary logs; delete all temporary logs before delivery.
- Fix at the source, do not mask symptoms: fix it where the bad data is first produced. After the root cause is fixed, do not casually add fallbacks where the error is reported; if a fallback is truly needed, raise it separately in the report and let the user decide.
- First ask why it was written wrong: determine whether this is an isolated case or a widespread problem. For widespread problems, investigate the whole repository and handle them together.
- Ask before changing persistent standards: before adding automated checks, changing
AGENTS.mdorREVIEW.md, first obtain the user's consent.
First determine whether this belongs here
When the user has already stated the cause and the fix (for example, "the text is wrong, change it to so-and-so"), handle it as a small fix: change it directly, run the relevant quick tests, report in two or three sentences, and skip the workflow below. When the repository AGENTS.md has a development conventions subsection whose title contains oil-dev , the quick test command and high-risk directories follow that subsection.
Workflow
1. Reproduce
First write a test that reproduces the problem, run it, confirm that it fails, and then continue. When a test cannot be written, use a command that can be run repeatedly or clear manual steps instead.
When it truly cannot be reproduced (it only occurs on the user's machine or in production), explain which logs and code reasoning the conclusion is based on, state in the report how confident you are and how the fix will be confirmed.
2. Find the root cause
Choose the least effortful method; for method details, see Root cause investigation methods:
- It worked before: narrow down between the good version and the bad version to the specific commit. When there are few commits, read
git logandgit diffdirectly; when there are many commits, usegit bisect, run it in a temporary worktree, and do not touch the current working tree. - There is one wrong value: trace back from the wrong output, add temporary logs at module boundaries, and find where it first becomes wrong.
- There is a working comparison(another input, platform, or configuration): run them simultaneously and narrow down the differences item by item.
The root cause is found only when both of the following are satisfied:
- You can state the complete causal chain from the trigger condition to the symptom, with each step corresponding to a code location;
- You can explain all observed symptoms, including why it did not appear before and why it only appears under certain conditions.
3. Determine whether it is an isolated case or a widespread problem
Ask "why was it written wrong":
- Isolated case: a slip of the hand, a missing branch. Fix only this one place.
- Widespread problem: The reason is a certain way of writing code or a misunderstanding, for example the same piece of logic copied several times, an interface whose usage is easy to get wrong, or a convention that was never written down.
If it is a widespread problem, search the whole repository for this way of writing code, list all the matching locations, and confirm one by one whether each really has the same problem.
4. Fix at the source
- Make the minimal change at the locations found in step 2. The following do not count as fixes: adding a null check, try/catch, retry, sleep, or a longer timeout at the error site when you cannot tell where the bad value comes from; writing a special case only for the reported input; loosening, skipping, or deleting failing tests; changing several places at once without being able to tell which one made the difference.
- Widespread problem: if the matching locations all need the same change, there are no more than 5 of them, and they are not in high-risk directories, fix them all together; beyond that scope, give the list to the user first, or hand it to
oil-planto write a plan. - Run the test from step 1 and confirm it passes. For other matching locations of a widespread problem, add a test for each, or explain why not.
- Run the quick tests for the relevant modules and delete all temporary logs.
If the fix requires changing high-risk directories, external interfaces, or data formats, tell the user the root cause and the fix first, and change only after confirmation.
5. Prevent recurrence
- Isolated case: the regression test from step 1 is enough.
- Widespread problem: propose a safeguard in the report and do it only after the user confirms:
- If a script or test can detect this way of writing code, write it as an automated check in the project (hand it to
oil-govern). Prefer this option, since checks do not miss things. - If it cannot be detected, add a review focus item to the existing rules in
AGENTS.md(if there are already many rules, put it inREVIEW.md)。oil-code-reviewwill read these files, and future reviews will focus on it.
- If a script or test can detect this way of writing code, write it as an automated check in the project (hand it to
Write each review focus item on one line, stating what to look at, why, and its source, for example:
- 把时间戳换成日期时一律指定 UTC,不用本地时区。(来源:每日报表日期差一天的修复)
Do not add a review focus item for a problem that matches only one location.
6. Report
**根因**:一句话说清。
**因果链**:触发条件 → `path:line` → … → 用户看到的现象
**引入时间**:引入问题的提交(查过历史时)
**个例还是普遍问题**:普遍问题时列出排查到的位置和处理结果
**改了什么**:修复位置,以及为什么改在这里
**验证**:修复前失败、修复后通过的测试和命令
**防再犯**:回归测试,以及提议的自动检查或审查重点
**没验证的部分**:例如打包后的环境
When the user wants to commit, use the same content for the commit message; do not create a separate defect document.
Stop-loss
Stop immediately if any of the following happens: two or three guesses in a row are disproven; tests still fail after two rounds of fixes; the conversation fills up with contradictory guesses.
- Compile the confirmed facts, the ruled-out guesses, and the reproduction steps into one page, and explain the current status to the user.
- When
oil-delegateis installed, use--role diagnoseto dispatch two independent read-only analyses with--role-slot 1and--role-slot 2respectively: the one that returnsUSE_HOSTis instead handled by a brand-new read-only sub-agent of the current Agent; when it returnsNEEDS_ROLE_CHOICE, ask the user once which two they want, and save them as described inoil-delegate. If not installed, start two brand-new read-only sub-agents. When they return, compare the conclusions from both sides and confirm thatgit statushas not changed. - If neither path yields a clean solution and the problem is a non-core, peripheral feature, propose simplifying the interaction or cutting the feature.
Output and follow-up handoff
| Downstream intent | Handoff action |
|---|---|
| The fix is large and requires cross-module changes or product trade-offs | Proceed to oil-plan to write a plan, with the root cause and investigation checklist |
| The fix touches high-risk directories, or the user requests a review | Proceed to oil-code-review, indicating that this is the defect fix and root cause location |
| the user agrees to write the general issue as an automated check | enter oil-govern to write an in-project check |
| fix complete, ready to merge | according to oil-plan 's wrap-up checklist, run the merge gate |
Resource navigation
- references/root-cause-methods.md: read during step 2 when finding the root cause; includes the commands for bisecting history in a temporary worktree, the approach of tracing the bad value backward and controlled experiments, and common sources of intermittent issues.