495 lines
22 KiB
Markdown
495 lines
22 KiB
Markdown
> Extracted from implement/SKILL.md (Mode: bugfix) — moved verbatim 2026-08-25, ticket [org-internal #3381].
|
||||
|
|
|
|||
|
|
### Mode: bugfix
|
|||
|
|
|
|||
|
|
Reproduce, isolate, and fix a bug with a regression test to prevent
|
|||
|
|
recurrence. For small, localized bugs, use standalone mode — the existing
|
|||
|
|
system behavior is the specification. For large, complex bugs, route through
|
|||
|
|
the full quality pipeline.
|
|||
|
|
|
|||
|
|
#### Process Overview
|
|||
|
|
|
|||
|
|
Every diamond below is a gate Developers rationalize skipping — especially
|
|||
|
|
under "the bug is obvious" pressure.
|
|||
|
|
|
|||
|
|
```dot
|
|||
|
|
digraph bugfix {
|
|||
|
|
rankdir=TB;
|
|||
|
|
node [shape=box, fontname="Helvetica"];
|
|||
|
|
|
|||
|
|
repro [shape=diamond, label="Bug reproduces?"];
|
|||
|
|
norepro [label="STOP: report cannot-reproduce\n(do not guess-patch)"];
|
|||
|
|
rc [shape=diamond, label="Root cause found\n(not just symptom)?"];
|
|||
|
|
symptom [label="Go deeper — do NOT\npatch the symptom"];
|
|||
|
|
route [shape=diamond, label="Routing:\nstandalone vs pipeline?"];
|
|||
|
|
escalate [label="Uncertain → escalate\nto pipeline mode"];
|
|||
|
|
rtest [shape=diamond, label="Regression test\nFAILS before fix?"];
|
|||
|
|
notest [label="Test does not cover\nthe bug — rewrite it"];
|
|||
|
|
fix [label="Phase 4: Fix\n(one change, root cause only)"];
|
|||
|
|
green [shape=diamond, label="Regression test PASS\n+ full suite green?"];
|
|||
|
|
done [shape=doublecircle, label="Phase 5/6:\nSelf-Check + Report"];
|
|||
|
|
|
|||
|
|
repro -> norepro [label="no"];
|
|||
|
|
repro -> rc [label="yes"];
|
|||
|
|
rc -> symptom [label="no"];
|
|||
|
|
rc -> route [label="yes"];
|
|||
|
|
route -> escalate [label="uncertain"];
|
|||
|
|
route -> rtest [label="standalone"];
|
|||
|
|
rtest -> notest [label="passes already"];
|
|||
|
|
rtest -> fix [label="fails (confirmed)"];
|
|||
|
|
fix -> green;
|
|||
|
|
green -> fix [label="no: fix + re-run"];
|
|||
|
|
green -> done [label="yes"];
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Execution Modes
|
|||
|
|
|
|||
|
|
| Mode | Entry Point | Scope Source | Review Gate | Verify Gate |
|
|||
|
|
| ---------- | -------------------------------------- | ------------------ | ------------ | ----------- |
|
|||
|
|
| Standalone | User says "fix this bug" | Bug report + code | Optional (>20 lines or ≥3 files) | None |
|
|||
|
|
| Pipeline | User requests full-process bugfix, or auto-escalation | Bug report → requirements → design → plan → implement | Mandatory | Mandatory |
|
|||
|
|
|
|||
|
|
> **Routing override (ticket-seeded)**: the Optional/None gate declarations
|
|||
|
|
> above apply to *user-initiated* standalone mode. When the ticket carries a
|
|||
|
|
> `Kind/*` route whose `keep_gates` includes `review-code` / `verify` (e.g.
|
|||
|
|
> `Kind/Bug`, `Kind/Testing` — see `<instance-root>/workflow-routing.yaml`), those
|
|||
|
|
> gates are MANDATORY regardless of size. Per `core/rules/workflow-routing.md`,
|
|||
|
|
> a gate is mandatory if EITHER the route OR the skill requires it; skipping is
|
|||
|
|
> valid only when BOTH agree it is skippable.
|
|||
|
|
|
|||
|
|
In pipeline mode, the bug report becomes a bugfix work item that flows through
|
|||
|
|
the full requirements → design → plan → implement → review-code → verify
|
|||
|
|
pipeline.
|
|||
|
|
|
|||
|
|
#### Role & Responsibilities
|
|||
|
|
|
|||
|
|
The bugfix is owned and executed by the **Developer** (Worker). The
|
|||
|
|
Developer owns both implementation and bugfix — same role, same skill set.
|
|||
|
|
|
|||
|
|
The Developer is responsible for:
|
|||
|
|
|
|||
|
|
- Reproducing the bug from the description.
|
|||
|
|
- Identifying the root cause (not just patching the symptom).
|
|||
|
|
- Writing a regression test that fails before the fix and passes after.
|
|||
|
|
- Applying the minimal surgical fix — one change, one purpose.
|
|||
|
|
- Running the full test suite to confirm no regressions.
|
|||
|
|
|
|||
|
|
The Builder's role is to present the bugfix report and route it to code
|
|||
|
|
review if the change is non-trivial (> 20 lines or touches ≥ 3 files).
|
|||
|
|
|
|||
|
|
#### Tester focus for bugfix
|
|||
|
|
|
|||
|
|
The Tester role in bugfix writes **regression tests** and, uniquely,
|
|||
|
|
intervenes BEFORE the fix (a regression test must fail before the fix to
|
|||
|
|
prove the bug exists):
|
|||
|
|
|
|||
|
|
- **Failing regression test** — read `repro-notes.md` (the Developer's
|
|||
|
|
reproduction + root-cause analysis from Phases 1–2), write a test that
|
|||
|
|
exercises the exact bug path and FAILS with the bug's symptom. This MUST
|
|||
|
|
happen before Phase 4 (Fix), not after — it is Phase 3.
|
|||
|
|
- **Passing confirmation** — after the Developer's fix, the same test MUST
|
|||
|
|
pass (the Developer's green run in Phase 4 verifies this).
|
|||
|
|
- **Boundary regression tests** — inputs adjacent to the bug trigger,
|
|||
|
|
similar conditions that must NOT trigger the fix (guards against
|
|||
|
|
over-fixing), and error paths near the root cause.
|
|||
|
|
|
|||
|
|
**Bugfix-specific orchestration** (overrides the standard role-split flow):
|
|||
|
|
|
|||
|
|
Because a regression test must fail BEFORE the fix, the bugfix role split
|
|||
|
|
inverts the standard orchestration — the Tester dispatches between
|
|||
|
|
Phase 2 and Phase 4, not after the fix:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
[Worker: developer] Phase 1 reproduce + Phase 2 root cause
|
|||
|
|
→ write repro-notes (reproduction steps, root cause, bug path,
|
|||
|
|
expected behavior)
|
|||
|
|
↓ persist: wiki page `{slug}/repro-notes` (gitea_wiki__create_page)
|
|||
|
|
[Worker: tester] read repro-notes → Phase 3 write failing regression test
|
|||
|
|
(confirms FAIL before fix)
|
|||
|
|
↓ persist: wiki page `{slug}/test-report` (gitea_wiki__create_page, failing test confirmed)
|
|||
|
|
[Worker: developer] Phase 4 fix → run test:changed to green
|
|||
|
|
→ write impl-notes (post-fix behavior contract)
|
|||
|
|
↓ persist: wiki page `{slug}/impl-notes` (gitea_wiki__create_page, post-fix behavior contract)
|
|||
|
|
[Worker: tester] supplement boundary regression tests → run test:changed
|
|||
|
|
↓ persist: update wiki page `{slug}/test-report` (gitea_wiki__update_page, final)
|
|||
|
|
— consumed by the human stakeholder / next iteration planning for DoD regression-test evidence
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
For small, single-file bugfixes with an obvious fix, a single Developer
|
|||
|
|
Worker may write the failing test, fix, and confirm green in one invocation
|
|||
|
|
— the split is optional for trivial fixes (Phase 3 + Phase 4 in one
|
|||
|
|
session). Force the split when the fix touches ≥ 2 files or the root cause
|
|||
|
|
spans ≥ 2 levels of indirection.
|
|||
|
|
|
|||
|
|
Pipeline-mode bugfixes route through the implement pipeline (see ### Mode:
|
|||
|
|
implement (default)), with the bugfix-specific Tester focus above layered
|
|||
|
|
on top of the standard role-split orchestration.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### Preconditions (standalone)
|
|||
|
|
|
|||
|
|
Before starting the bugfix, confirm:
|
|||
|
|
|
|||
|
|
- [ ] Bug description exists (user's message, issue tracker link, or error log).
|
|||
|
|
- [ ] Existing codebase is accessible.
|
|||
|
|
- [ ] `core/checklists/bugfix.md` is accessible.
|
|||
|
|
|
|||
|
|
If the user describes a symptom without specifics, ask for:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
To fix this bug, I need:
|
|||
|
|
1. What is the expected behavior? (what should happen)
|
|||
|
|
2. What is the actual behavior? (what happens instead)
|
|||
|
|
3. Steps to reproduce.
|
|||
|
|
4. Any error messages, logs, or stack traces.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### Routing Decision
|
|||
|
|
|
|||
|
|
After Phase 1 (reproduce) and Phase 2 (root cause), the Developer evaluates
|
|||
|
|
whether the fix qualifies for standalone or pipeline mode:
|
|||
|
|
|
|||
|
|
**Escalate to pipeline mode when ANY of:**
|
|||
|
|
|
|||
|
|
| Condition | Reason |
|
|||
|
|
| --------------------------------------------------- | ------------------------------------------------------------ |
|
|||
|
|
| Fix touches ≥ 5 files | Cross-file changes need design review and integration tests |
|
|||
|
|
| Fix spans ≥ 2 modules / components | Multi-module fixes need architectural validation |
|
|||
|
|
| Root cause is in a design-level decision (protocol, schema, architecture) | Design change needs requirements + design review |
|
|||
|
|
| Fix requires data migration or schema change | Schema changes need data design review and migration plan |
|
|||
|
|
| Fix changes a public API or interface contract | API changes need interface design review and compatibility check |
|
|||
|
|
| Fix introduces a new dependency or changes an existing one | Dependency changes need review (DGN dimension, code review) |
|
|||
|
|
| Estimated lines changed > 50 | Large change carries high regression risk |
|
|||
|
|
| User explicitly requests full-process bugfix | User wants quality gates |
|
|||
|
|
|
|||
|
|
**Stay in standalone mode when ALL of:**
|
|||
|
|
|
|||
|
|
| Condition |
|
|||
|
|
| ---------------------------------------------- |
|
|||
|
|
| Fix is ≤ 4 files |
|
|||
|
|
| Fix is ≤ 1 module / component |
|
|||
|
|
| Fix is a logic error, not a design error |
|
|||
|
|
| No data migration or schema change |
|
|||
|
|
| No API or interface contract change |
|
|||
|
|
| No dependency change |
|
|||
|
|
| Estimated lines changed ≤ 50 |
|
|||
|
|
|
|||
|
|
If the Developer is uncertain, escalate. A false pipeline escalation costs a few
|
|||
|
|
extra review rounds. A false standalone decision risks missing a quality gate on
|
|||
|
|
a complex change.
|
|||
|
|
|
|||
|
|
**Big-bug relabel rule ([org-internal #3061])** — before the generic escalation below, split
|
|||
|
|
the triggers by kind:
|
|||
|
|
|
|||
|
|
- **Design-level triggers** (root cause is a design decision — protocol /
|
|||
|
|
schema / architecture; shared-contract or public-API change; data
|
|||
|
|
migration): do NOT push through bugfix and do NOT run the legacy pipeline
|
|||
|
|
escalation — **relabel the ticket `Kind/Feature`** and reroute via Step 0
|
|||
|
|
(DAG route; a 1–3 node small DAG is the expected shape for a single
|
|||
|
|
design-level fix). The fix work already done (repro notes, root cause)
|
|||
|
|
becomes node input, not wasted work.
|
|||
|
|
- **Mechanical size triggers only** (many files / many lines, same design):
|
|||
|
|
stay in bugfix — batch the change into iterations and keep the
|
|||
|
|
review-code + verify gates. Scale alone never justifies a relabel.
|
|||
|
|
|
|||
|
|
When escalating, the Developer pauses after Phase 2, reports the routing
|
|||
|
|
decision, and asks the user to confirm pipeline escalation:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
This bugfix qualifies for pipeline mode:
|
|||
|
|
- {N} files across {M} modules
|
|||
|
|
- Root cause: {design-level issue}
|
|||
|
|
- Estimated lines: {N}
|
|||
|
|
|
|||
|
|
→ Route through requirements → design → plan → implement → review → verify?
|
|||
|
|
(yes / no — proceed with standalone)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### Phase 1 — Understand & Reproduce
|
|||
|
|
|
|||
|
|
1. **Read relevant code** — find the module/component likely responsible for
|
|||
|
|
the bug. Use `grep` for error messages, `glob` for related files.
|
|||
|
|
|
|||
|
|
2. **Check existing tests** — do existing tests cover this code path? If a
|
|||
|
|
test exists but passes, the bug is in the test or in an uncovered branch.
|
|||
|
|
|
|||
|
|
3. **Reproduce** — run the relevant test(s) or manually trigger the bug.
|
|||
|
|
Confirm the actual behavior matches the bug report. Document the
|
|||
|
|
reproduction:
|
|||
|
|
|
|||
|
|
```markdown
|
|||
|
|
## Reproduction
|
|||
|
|
|
|||
|
|
**Steps**:
|
|||
|
|
|
|||
|
|
1. {step}
|
|||
|
|
2. {step}
|
|||
|
|
**Expected**: {what should happen}
|
|||
|
|
**Actual**: {what happens}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
4. If the bug CANNOT be reproduced, stop and report:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Cannot reproduce the bug. Here's what I tried:
|
|||
|
|
- {step 1}
|
|||
|
|
- {step 2}
|
|||
|
|
|
|||
|
|
→ Is the environment different? Are there missing steps? Does a specific
|
|||
|
|
data state trigger it?
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### Phase 2 — Isolate Root Cause
|
|||
|
|
|
|||
|
|
Trace from the symptom to the root cause:
|
|||
|
|
|
|||
|
|
1. **Symptom**: surface-level error (e.g. "500 on login").
|
|||
|
|
2. **Proximate cause**: the code that throws or returns wrong (e.g. "password
|
|||
|
|
hash comparison returns false for valid password").
|
|||
|
|
3. **Root cause**: the underlying defect (e.g. "password hashing config changed
|
|||
|
|
in commit abc123 but the stored hashes were not re-hashed").
|
|||
|
|
|
|||
|
|
```markdown
|
|||
|
|
## Root Cause Analysis
|
|||
|
|
|
|||
|
|
**Symptom**: {error message or wrong behavior}
|
|||
|
|
**Proximate cause**: {file}:{line} — {what the code does wrong}
|
|||
|
|
**Root cause**: {underlying defect — config, data, logic, or assumption}
|
|||
|
|
|
|||
|
|
**Introduced in**: {commit hash or version if known}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Rules**:
|
|||
|
|
|
|||
|
|
- If you're fixing a symptom (e.g. adding a null check where the real bug is
|
|||
|
|
that null should never reach that line), stop and go deeper.
|
|||
|
|
- If you can't find the root cause after examining 3 levels of indirection,
|
|||
|
|
pause and report findings. Do NOT apply a surface-level patch.
|
|||
|
|
- **After Phase 2, evaluate the routing decision** (see Routing Decision table
|
|||
|
|
above). If the fix qualifies for pipeline mode, pause and present the
|
|||
|
|
escalation prompt before proceeding to Phase 3.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### Phase 3 — Write a Regression Test
|
|||
|
|
|
|||
|
|
Before fixing, write a test that proves the bug exists:
|
|||
|
|
|
|||
|
|
1. Write a test that exercises the bug path with the failing inputs.
|
|||
|
|
2. Run the test — it MUST fail with the bug's symptom.
|
|||
|
|
3. The test must be specific: test the exact condition that was broken, not
|
|||
|
|
a general "endpoint returns 200" test.
|
|||
|
|
|
|||
|
|
```markdown
|
|||
|
|
## Regression Test
|
|||
|
|
|
|||
|
|
- **File**: {path to test file}
|
|||
|
|
- **Test name**: {test function name}
|
|||
|
|
- **What it verifies**: {the expected behavior that was broken}
|
|||
|
|
- **Fails before fix**: ✅ (confirmed)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Rules**:
|
|||
|
|
|
|||
|
|
- If you cannot write a test that fails (bug is non-deterministic, environment-
|
|||
|
|
specific), write the most targeted test you can and mark it `[flaky]`.
|
|||
|
|
- The test must fail NOW, before you apply the fix. If it passes already, the
|
|||
|
|
test does not cover the bug.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### Phase 4 — Fix
|
|||
|
|
|
|||
|
|
Apply the minimum change that resolves the root cause:
|
|||
|
|
|
|||
|
|
1. **One conceptual change per fix** — do not bundle a bugfix with refactoring,
|
|||
|
|
style changes, or "while I'm here" improvements.
|
|||
|
|
2. **Fix the root cause**, not the symptom. If the root cause is in a different
|
|||
|
|
file than the symptom, fix it there.
|
|||
|
|
3. **Update only what's necessary** — if fixing a null-safety bug requires
|
|||
|
|
adding a null check in one place, add one null check, not a comprehensive
|
|||
|
|
null-safety overhaul of the entire module.
|
|||
|
|
4. Run the regression test — it MUST pass.
|
|||
|
|
5. Run the relevant unit tests — all existing tests must still pass.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### Phase 5 — Self-Check & Report
|
|||
|
|
|
|||
|
|
##### Self-Check
|
|||
|
|
|
|||
|
|
1. **Typecheck**: `bun typecheck` — zero errors.
|
|||
|
|
2. **Lint**: `bun oxlint --deny-warnings` — zero errors.
|
|||
|
|
3. **Full test suite**: `bun run test:parallel` — all tests pass (new + existing).
|
|||
|
|
4. **Checklist**: verify every item in `core/checklists/bugfix.md`.
|
|||
|
|
5. **Publish bugfix report**: write the bugfix report as a wiki page via `wiki 读写 API(见 TERMINOLOGY)` with page_name `{slug}/bugfix-report` (`_shared/gitea-write-patterns.md` Pattern 1).
|
|||
|
|
|
|||
|
|
##### Report
|
|||
|
|
|
|||
|
|
```markdown
|
|||
|
|
## Bugfix Report
|
|||
|
|
|
|||
|
|
**Bug**: {one-line description}
|
|||
|
|
**Root cause**: {file}:{line} — {explanation}
|
|||
|
|
**Fix**: {file} — {single-sentence description of change}
|
|||
|
|
**Lines changed**: {N}
|
|||
|
|
**Regression test**: {test file}:{test name}
|
|||
|
|
|
|||
|
|
### Verification
|
|||
|
|
|
|||
|
|
- Regression test: {PASS | FAIL}
|
|||
|
|
- Full test suite: {N} passed, 0 failed
|
|||
|
|
- Typecheck: ✅
|
|||
|
|
- Lint: ✅
|
|||
|
|
|
|||
|
|
### Files Changed
|
|||
|
|
|
|||
|
|
| File | Lines | Purpose |
|
|||
|
|
| ------------------- | ------ | ------------------------------------------------------ |
|
|||
|
|
| `src/auth/login.ts` | +3, -1 | Fix password hash comparison when salt version changes |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**Handoff**: {if changes > 20 lines or ≥ 3 files → run `core/skills/review-code/SKILL.md`
|
|||
|
|
| otherwise → fix complete, no review needed}
|
|||
|
|
|
|||
|
|
> **Routing override**: when the ticket carries a `Kind/*` route whose
|
|||
|
|
> `keep_gates` includes `review-code` / `verify` (e.g. `Kind/Bug`,
|
|||
|
|
> `Kind/Testing`), those gates are MANDATORY even for small fixes — the
|
|||
|
|
> "no review needed" branch above does not apply (see the Execution Modes
|
|||
|
|
> routing-override note above).
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### Phase 5.5 — Issue Checklist Sync (standalone bugfix)
|
|||
|
|
|
|||
|
|
In standalone-bugfix mode there are no skill-exit boundaries between commit,
|
|||
|
|
PR, review, and CI — without explicit sync points the issue goes stale. Per
|
|||
|
|
the `issue-checklist-sync` L1 rule, sync at each externally visible
|
|||
|
|
transition (skip any step if no source issue exists):
|
|||
|
|
|
|||
|
|
| When | Sync action |
|
|||
|
|
|------|-------------|
|
|||
|
|
| After the fix commit | Check off fix-delivered ACs with `_(commit {sha}: file)_` |
|
|||
|
|
| After PR creation | Ensure the `## 当前状态` section exists (the PR row is auto-written by the status-sync poller — see `issue-checklist-sync.md` § Automated sync) |
|
|||
|
|
| After review convergence | Review-related ACs get `_(reviewed: round N PASS)_` (done by review-code Phase E 2.7) |
|
|||
|
|
| On CI state transitions | Update process-AC progress (e.g. "N consecutive green") with run number |
|
|||
|
|
| At verify PASS / close | Final sweep per `verify` Phase 5.6 |
|
|||
|
|
|
|||
|
|
Bugfix mode delegates the "after commit" step to the same mechanics as Phase
|
|||
|
|
4.6 above (fetch issue body → map `- [ ]` items → `工单 API(见 TERMINOLOGY)update`), and
|
|||
|
|
the PR-creation step to Phase 4.7.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### Phase 6 — Approval
|
|||
|
|
|
|||
|
|
Present the report:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Bug fixed: {one-line description}
|
|||
|
|
- Root cause: {file}:{line}
|
|||
|
|
- {N} lines changed in {M} files
|
|||
|
|
- Regression test added: {test name}
|
|||
|
|
- Full test suite: ✅
|
|||
|
|
|
|||
|
|
→ {if review needed: "Run code review?" | else: "Fix complete. Approve?"}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### Common Rationalizations (bugfix)
|
|||
|
|
|
|||
|
|
Bugfixes fail from **pressure and false confidence** far more than from
|
|||
|
|
ignorance — "the bug is obvious" is the thought that precedes a symptom patch,
|
|||
|
|
a bundled diff, or a regression that surfaces weeks later. These are the
|
|||
|
|
excuses that precede every reopened bug. If you catch yourself thinking any
|
|||
|
|
row's "Excuse", stop: the "Reality" column is the exact rule you are about to
|
|||
|
|
break.
|
|||
|
|
|
|||
|
|
| Excuse | Reality (the rule being broken) |
|
|||
|
|
|--------|---------------------------------|
|
|||
|
|
| "Just add a null check where it crashes" | Symptom-patching. Phase 2: if you are fixing a symptom, stop and go deeper — the real defect is whatever let null reach that line. |
|
|||
|
|
| "Can't reproduce, but I'm sure it's X" | Phase 1: if the bug cannot be reproduced, stop and report. Guess-patching a non-reproduced bug fixes nothing verifiable. |
|
|||
|
|
| "3 levels deep, can't find it, patch the symptom" | Phase 2: after 3 levels of indirection with no root cause, pause and report — do NOT apply a surface patch. |
|
|||
|
|
| "Bug's obvious, I'll fix then add the test" | Phase 3: the regression test MUST fail before the fix. Fix-first means you test your fix, not the bug. |
|
|||
|
|
| "Test passed immediately, ship it" | Phase 3 Rules: a test that passes before the fix does not cover the bug — rewrite it until it fails. |
|
|||
|
|
| "While I'm in this file, also clean up…" | Phase 4 rule 1: one conceptual change per fix. Bundling refactors/style/other-fixes pollutes the regression signal. |
|
|||
|
|
| "Make the whole module null-safe while I'm here" | Phase 4 rule 3: update only what is necessary. Over-fixing turns a 3-line surgical fix into a high-risk diff. |
|
|||
|
|
| "Fix is isolated, skip the full suite" | Phase 4 rule 5 + Phase 5: the full suite catches regressions your isolated view cannot. |
|
|||
|
|
| "4 files but one module, standalone's fine" | Routing Decision: escalate when uncertain. A false-standalone call skips quality gates on a complex change. |
|
|||
|
|
|
|||
|
|
##### Incident Triage Carve-Out
|
|||
|
|
|
|||
|
|
When the bugfix occurs under **active production incident** pressure
|
|||
|
|
(user-facing outage, on-call escalation), the Phase 2→3 ordering can be
|
|||
|
|
**temporarily relaxed** — but never skipped:
|
|||
|
|
|
|||
|
|
1. A stop-gap (symptom patch) MAY ship first to restore service.
|
|||
|
|
2. BUT the full root-cause trace + failing regression test + proper
|
|||
|
|
root-cause fix MUST land in the **same incident window** — never deferred
|
|||
|
|
to "tomorrow" or "a follow-up ticket".
|
|||
|
|
3. If you defer, you have not fixed the bug — you have shipped a symptom patch
|
|||
|
|
with a promise. Promises are not regression tests.
|
|||
|
|
|
|||
|
|
This carve-out exists because the rationalization table above cannot resolve a
|
|||
|
|
*legitimate* priority conflict (service down vs process discipline). It
|
|||
|
|
resolves it by permitting triage but forbidding deferral.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### Pipeline Mode (bugfix)
|
|||
|
|
|
|||
|
|
> **Legacy path retired ([org-internal #3072] phase 3, 2026-08-21)**: the full
|
|||
|
|
> requirements-elicitation → design → review-artifact(design-space) →
|
|||
|
|
> plan-iterations → review-artifact(plan) front-end was archived
|
|||
|
|
> (`<instance-root>/archive/skills/`). A big bug that needs a design-level decision
|
|||
|
|
> now relabels `Kind/Feature` and enters the DAG route (see the big-bug
|
|||
|
|
> relabel rule above) — repro + root-cause notes carry over as node input.
|
|||
|
|
> The abort criteria below still apply to any multi-stage bug run before
|
|||
|
|
> code is written.
|
|||
|
|
|
|||
|
|
When a bugfix escalates beyond standalone scope, the bug report becomes a
|
|||
|
|
pipeline input; the original bugfix phases (reproduce, root cause, regression
|
|||
|
|
test, fix) are embedded within the implement stage, and review-code + verify
|
|||
|
|
remain mandatory gates.
|
|||
|
|
|
|||
|
|
##### Pipeline Abort Criteria
|
|||
|
|
|
|||
|
|
Before any code is written in pipeline mode, abort the pipeline if ANY of:
|
|||
|
|
|
|||
|
|
| # | Condition | Action |
|
|||
|
|
|---|-----------|--------|
|
|||
|
|
| 1 | Bug no longer reproduces after environment change (strace re-isolation returns 0 reproductions, user confirms symptom resolved) | Write ABORT to wiki page `{slug}/ABORT` (wiki 读写 API(见 TERMINOLOGY)), preserve all completed artifacts, run retrospective |
|
|||
|
|
| 2 | Root cause hypothesis is falsified during re-isolation (e.g., strace shows suspected git spawn is NOT hanging) | Write ABORT.md, escalate to Architect for design revision OR abort pipeline |
|
|||
|
|
| 3 | Bug is resolved by external change (new binary build, dependency update, OS/kernel patch) | Write ABORT.md with resolution evidence, close without code changes |
|
|||
|
|
| 4 | Reproduction confidence < 3/5 after re-isolation attempt | Write ABORT.md if confidence cannot be improved within 1 re-isolation iteration |
|
|||
|
|
|
|||
|
|
**Abort procedure**:
|
|||
|
|
1. Write ABORT to wiki page `{slug}/ABORT` (wiki 读写 API(见 TERMINOLOGY)) documenting the reason, evidence, and which artifacts are preserved.
|
|||
|
|
2. Do NOT commit or merge the bugfix branch (no code was written).
|
|||
|
|
3. Run retrospective to extract process improvements.
|
|||
|
|
4. Archive artifacts to wiki page `_archive/{slug}/` (wiki 读写 API(见 TERMINOLOGY)) after retrospective.
|
|||
|
|
|
|||
|
|
**Scope**: these criteria apply before the implement stage. Once code is written, the pipeline proceeds through review-code → verify — abort is no longer valid.
|
|||
|
|
|
|||
|
|
##### Stage: Implement → Code Review → Verify
|
|||
|
|
|
|||
|
|
On the DAG route a bug-fix node's spec (ACs tracing to the repro + root cause)
|
|||
|
|
lives in `{epic-slug}/dag`; the Developer follows the bugfix Phases 1–6 (from
|
|||
|
|
standalone mode above) as the implementation method, then produces the
|
|||
|
|
standard implementation report (see ### Mode: implement (default), Phase 5).
|
|||
|
|
Code review runs all 10 dimensions against the bugfix changes. Verify runs
|
|||
|
|
the full DoD matrix including regression tests, integration tests, and NFR
|
|||
|
|
validation. Output pages: code review → `{slug}/reviews/code/final/report`;
|
|||
|
|
verification → `{slug}/05-verify-iteration-1`.
|