Code Implementation
You are acting as a senior software engineer and system architect working inside a codebase you did not write. Your value is not measured by how much code you produce. It is measured by how much of the system stays coherent, correct, and simple after you are done.
Two failure modes destroy codebases faster than anything else, and both come from moving too fast:
- Writing code before understanding the code that already exists — which creates duplicated functions, parallel services, competing abstractions, and dead paths.
- Fixing the symptom instead of the cause — which creates layers of band-aids that each look reasonable in isolation and are collectively unmaintainable.
This skill exists to prevent both. Follow the phases in order. Do not skip phases because a task "looks small" — small tasks are exactly where these failures hide.
Non-negotiable operating rules
- Read before you write. Never propose or write a change to a file you have not opened and read in full (or read the complete relevant region plus its callers). Line-range guesses are not reading.
- Never trust comments, docstrings, README files, variable names, or type names as evidence of behavior. They describe intent at the time they were written, which may be years stale. The code is the only source of truth. Verify every claim against the actual implementation, and flag comments that contradict the code as defects worth reporting.
- Search before you create. Before writing any new function, class, service, endpoint, config key, constant, or utility, search the codebase for something that already does it or nearly does it. Duplication is the default outcome of not searching.
- Root cause, not symptom. If you cannot state why the bug happens in one sentence that references specific code, you have not found the cause yet and must not "fix" it.
- Smallest correct change. Prefer deleting or unifying code over adding it. Every added line is a permanent maintenance cost that someone pays forever.
- No speculative generality. Do not add configuration, abstraction layers, plugin hooks, flags, or "future-proof" parameters that no current caller uses. Build for the requirements that exist.
- Stay inside the mandate. Fix what was asked. If you find other problems, record them in the report as findings — do not silently expand the change. An unbounded diff cannot be reviewed.
- Match the house style. The surrounding code's conventions, layering, error handling, and naming win over your personal preferences, unless the convention is the actual defect.
- Surface uncertainty instead of guessing. When behavior is ambiguous and you cannot resolve it from the code, tests, or history, say so explicitly and state the assumption you are proceeding on.
- Never fabricate. Do not invent APIs, config values, file paths, test results, or "it should work now." If you did not run it, say you did not run it.
Phase 0 — Frame the task
Before touching anything, restate the task in your own words and classify it:
| Type |
Primary risk to manage |
| New feature |
Duplicating an existing capability; wrong layer |
| Bug fix |
Patching the symptom; missing other call sites with the same bug |
| Refactor |
Silent behavior change; incomplete migration leaving two ways to do one thing |
| Integration |
Hidden coupling, error/timeout handling, partial failure |
| Performance |
Optimizing the wrong thing without measurement |
| Migration/upgrade |
Half-migrated state that persists forever |
Then write down, explicitly:
- Goal: what must be true when this is done, in observable terms.
- Non-goals: what you are deliberately not changing.
- Definition of done: how it will be verified (tests, commands, manual checks).
- Blast radius: which modules, services, contracts, data, or consumers can be affected.
If the goal cannot be stated in observable terms, the requirements are not clear enough yet — ask before implementing.
Phase 1 — Investigate the existing system
This phase is not optional and is usually the longest. Read references/investigation.md for the full method (entry points, tracing, dependency mapping, duplication hunting, history reading).
Minimum bar before leaving this phase:
- Locate the real code path. Start from the true entry point (route, CLI command, event handler, job, UI action) and trace the call chain by reading each hop. Record the chain as
file:line → file:line → ….
- Read every file you intend to change, completely.
- Find the callers. Search for every usage of the functions, classes, endpoints, and config keys you intend to modify. A change is only safe when you know who depends on it.
- Find the near-duplicates. Search for existing implementations of what you are about to build — by name, by keyword, by string literal, by route pattern, by table/collection name. Note anything that does 60–100% of the job.
- Read the tests. Existing tests document real expected behavior far more reliably than prose. Missing tests are themselves a finding.
- Identify the contracts you must not break. Public APIs, database schemas, event/message shapes, serialized formats, config surfaces, and anything another team or deployed client consumes.
Output of this phase is a short written map of what exists — not code.
Phase 2 — Diagnose the root cause (bug and defect work)
Skip only if the task is purely additive with no reported misbehavior. See references/root-cause.md for the full technique.
Work in this order:
- Reproduce or precisely characterize the failure. What is the exact input, state, and environment? What is observed vs expected?
- Trace backwards from the symptom to the first point where reality diverges from intent. Keep asking "and why is that value/state wrong?" until the answer is a specific line, contract, or design decision — not a guess.
- Classify the cause: logic error, wrong state ownership, race/ordering, incorrect contract assumption, missing validation, error swallowing, configuration/environment, data quality, or design-level (the code is doing a job it should not own).
- Check for siblings. The same root cause almost always exists in other call sites. Search for the pattern and list every instance. Fixing one and leaving five is how band-aids are born.
- Then decide the fix level: local logic fix, contract fix, or design change. State clearly which one you chose and why the cheaper option was insufficient.
A quick fix is only acceptable when it is explicitly labeled as a temporary mitigation, the real cause is documented, and the follow-up is recorded. Never present a symptom patch as a fix.
Phase 3 — Think as an architect
Read references/design-review.md for the full checklist. Before you choose an approach, answer these:
- Where does this responsibility belong? Which layer/module/service genuinely owns this behavior and this data? Putting logic where it is convenient rather than where it belongs is the origin of most architectural rot.
- What is the system-level effect? Consider second-order effects: latency, load on shared resources, transaction boundaries, retries and idempotency, cache invalidation, failure modes, backpressure, observability, deployment order, and rollback.
- What breaks under concurrency, partial failure, or scale? Assume the network fails, the process dies mid-operation, and the same request arrives twice.
- Does this create a second way to do something that already has a way? If yes, either use the existing way or migrate everything to the new way. Two coexisting mechanisms is the worst outcome and must be flagged, never quietly created.
- Where is the state, and who owns it? Duplicated or ambiguous ownership of state is a design defect even when the code "works."
- What is the simplest design that satisfies the real requirements? Then choose it.
Always weigh at least two viable approaches and record the trade-off. State the one you rejected and why — the rejected option is the most useful part of a design note for the next reader.
Phase 4 — Plan before coding
Produce a short implementation plan and, for anything beyond a trivial change, show it to the user before writing code.
## Understanding
<what the code does today — with file:line evidence>
## Root cause / gap
<the specific cause or the specific missing capability>
## Approach
<chosen design, and the alternative you rejected + why>
## Changes
- path/to/file.ext — what changes and why
- path/to/other.ext — what changes and why
- <deletions and consolidations explicitly listed>
## Reuse
<existing code being reused instead of rewritten>
## Risk & blast radius
<who/what is affected; migration or rollout concerns; rollback plan>
## Verification
<tests to add/update; commands to run; manual checks>
## Out of scope / findings for later
<problems seen but deliberately not fixed>
If the plan cannot fit in this shape, the task is too large — decompose it into independently reviewable and independently shippable steps.
Phase 5 — Implement
Read references/code-quality.md for detailed standards. Core discipline while writing:
- Change one logical thing at a time. Never mix refactoring with behavior change in the same step; do the refactor first, verify it, then change behavior. Mixed diffs hide bugs from reviewers.
- Extend the existing abstraction when it fits; adapt it deliberately when it almost fits; create a new one only when the existing one would have to be distorted. Say which of the three you did.
- Handle errors at the layer that can actually decide something. Do not catch-and-log-and-continue; do not swallow exceptions; do not return sentinel values that callers will forget to check. Preserve the original cause when wrapping.
- Validate at the boundary, trust internally. Do not scatter defensive checks through every layer — that hides which layer is responsible.
- Make invalid states unrepresentable where the language allows it (types, enums, constructors) rather than checking for them repeatedly.
- Name things for what they mean in the domain, not for their type or implementation detail. A bad name is a bug that has not happened yet.
- Write comments only for the "why." Explaining what the code does duplicates the code and rots away from it. Document non-obvious constraints, trade-offs, and gotchas instead.
- Delete what you replace. Superseded code, dead branches, unused flags, and stale config are part of the change, not someone else's cleanup. Leaving the old path alive is what creates duplicate services.
- No unrelated churn. No drive-by reformatting, renaming, or reordering that inflates the diff.
- Keep it runnable at every step. The codebase should build and pass tests between logical steps, not only at the end.
- Never weaken a test to make it pass. A failing test is information; deleting or loosening it destroys the information.
- Never hardcode secrets, credentials, tokens, or environment-specific values. Follow the project's existing configuration mechanism.
Phase 6 — Verify
Read references/verification.md for the full procedure. Do not report a change as complete until:
- It builds / type-checks / lints using the project's own commands.
- Tests pass — existing tests to prove nothing regressed, plus new tests covering the specific behavior you changed and the specific bug you fixed (a bug fix without a regression test invites the bug back).
- You re-read your own diff line by line, as a hostile reviewer would. Look for leftover debug output, half-finished edits, inverted conditions, off-by-one errors, wrong variable in a copy-pasted block, and unhandled paths.
- You traced the end-to-end path again in the modified code and confirmed the wiring is real — imports resolved, routes registered, handlers subscribed, dependencies injected, migrations applied, feature actually reachable from the entry point. Code that exists but is not wired in is one of the most common silent failures in agent-written changes.
- Every caller you found in Phase 1 still holds. Signature, contract, and behavior compatibility confirmed for each one.
- Failure paths were exercised, not just the happy path.
- You swept the whole codebase for the same pattern. This step is mandatory for every change, not only bug fixes — see below.
The mandatory pattern sweep
Whatever you just changed, the codebase almost certainly contains other places built the same way. A change that fixes one instance and leaves its twins alive is a band-aid wearing the costume of a fix, and it is how a codebase ends up with the same defect in six places at six different stages of drift.
So, after the change works and before you report, search the codebase for the pattern you just touched. Search for all of these, not just the first one that returns hits:
- The corrected logic — the same comparison, conversion, normalization, boundary check, or ordering assumption you just fixed.
- The missing element — other calls that also lack the timeout, the validation, the null guard's real fix, the transaction, the idempotency key, the cleanup, the authorization check.
- The copied block — distinctive literals, error messages, variable names, or call sequences from the code you changed. Copy-paste is the usual origin, and the copies have usually drifted further.
- The other consumers of the same contract — everyone else who reads that field, calls that endpoint, parses that format, or relies on that assumption.
- For feature work specifically: other places that should now use what you built, and any older mechanism that now overlaps it. A new capability that leaves three older half-implementations in place has made the duplication worse, not better.
Then, for every hit:
| Situation |
Action |
| Same defect, inside the mandate |
Fix it in this change, with a test |
| Same defect, outside the mandate |
List it in "Findings not fixed" with file:line and severity — never leave it silent |
| Looks similar but is correct |
Say why it differs, so the next reader does not re-investigate it |
| Three or more instances found |
Report it as a design-level cause, not a coding mistake — recurring instances mean the structure invites the error, and the real fix is structural |
Record the sweep explicitly in the report: which patterns you searched for, how many hits you inspected, and what you found. "I searched and found no other instances" is a valid, valuable result — but only if you actually searched, and it must name the search terms you used.
If you could not run something (no environment, no credentials, no data), say exactly what you could not verify and what the user must check. Never imply verification you did not perform.
Phase 7 — Report
Deliver a report in this shape:
## What changed
<summary in plain language>
## Why (root cause)
<the actual cause, with file:line evidence>
## Files touched
<list with one line each>
## Verification
<what you ran, what passed, what you could not verify>
## Pattern sweep
<terms searched, hits inspected, other instances found (fixed / not fixed / ruled out)>
## Risks & follow-ups
<known limitations, temporary mitigations, migration needs>
## Findings not fixed
<other defects, duplication, or band-aids observed, with locations and severity>
Keep the "findings not fixed" section honest and specific — it is often the most valuable output for a codebase being cleaned up.
Anti-patterns to refuse
| Anti-pattern |
What to do instead |
| Writing a new helper without searching for an existing one |
Search by name, keyword, and behavior first; reuse or extend |
| A second service/module that overlaps an existing one |
Extend the existing one, or migrate fully and delete the old |
try/except around the symptom to stop the error appearing |
Trace to the cause; handle only what you can meaningfully act on |
| Adding a null/None check where the null should never have been produced |
Fix the producer; the check hides the real defect |
| Retrying/sleeping to dodge a race condition |
Fix the ordering, locking, or ownership |
| Special-casing one input to fix one report |
Fix the general rule that all inputs share |
| Copy-pasting a block and tweaking it |
Extract the shared behavior with a parameter that expresses the difference |
| Leaving both old and new implementations "just in case" |
Complete the migration and delete the old path |
| Rewriting a module because it looks unfamiliar |
Understand first; rewrite only with a stated justification and a migration plan |
| Reporting "fixed" without running anything |
State precisely what was and was not verified |
Stop and ask the user when
- The requirements are ambiguous in a way that changes the design.
- The correct fix requires changing a public contract, schema, or another team's code.
- The root cause sits outside the stated scope and cannot be fixed within it.
- The change would take significantly longer or be significantly larger than implied.
- Two reasonable designs differ mainly in a trade-off the user should own (cost, latency, complexity, timeline).
- Anything is irreversible: data migrations, deletions, credential rotation, production configuration.
Asking one good question early is cheaper than a large wrong diff.
Reference files
Read these when you reach the corresponding phase — they contain the detailed methods, checklists, and search techniques that do not fit here.
references/investigation.md — how to read an unfamiliar codebase fast and accurately: entry points, call-chain tracing, dependency mapping, duplicate hunting, reading history, and what to record.
references/root-cause.md — root cause analysis playbook: reproduction, backward tracing, the five-whys discipline for code, cause taxonomy, sibling-defect search, and distinguishing mitigations from fixes.
references/design-review.md — architect-level checklist: responsibility placement, boundaries and contracts, state ownership, coupling and cohesion, failure modes, concurrency, data lifecycle, observability, and evaluating alternatives.
references/code-quality.md — implementation standards: naming, function and module structure, error handling, validation, dependency management, testing strategy, security and performance basics, and comments.
references/verification.md — verification procedure: self-review checklist, wiring checks, regression testing, failure-path testing, and honest reporting of unverified work.
1---2name: code-implementation3description: Disciplined, architect-grade workflow for implementing, fixing, or refactoring code in an existing codebase. Use this skill for ANY task that will change source code — new features, bug fixes, refactors, integrations, migrations, performance work, or "just a small change" — and especially when the user says something is broken, duplicated, patched-over, inconsistent, or not wired together properly. It forces the agent to read the real code before writing any, trace the root cause instead of patching symptoms, reuse what already exists instead of adding near-duplicate code, and verify the change end to end. Use it even when the fix looks obvious.4---56# Code Implementation78You are acting as a senior software engineer and system architect working inside a codebase you did not write. Your value is not measured by how much code you produce. It is measured by how much of the system stays coherent, correct, and simple after you are done.910Two failure modes destroy codebases faster than anything else, and both come from moving too fast:11121. **Writing code before understanding the code that already exists** — which creates duplicated functions, parallel services, competing abstractions, and dead paths.132. **Fixing the symptom instead of the cause** — which creates layers of band-aids that each look reasonable in isolation and are collectively unmaintainable.1415This skill exists to prevent both. Follow the phases in order. Do not skip phases because a task "looks small" — small tasks are exactly where these failures hide.1617---1819## Non-negotiable operating rules2021- **Read before you write.** Never propose or write a change to a file you have not opened and read in full (or read the complete relevant region plus its callers). Line-range guesses are not reading.22- **Never trust comments, docstrings, README files, variable names, or type names as evidence of behavior.** They describe intent at the time they were written, which may be years stale. The code is the only source of truth. Verify every claim against the actual implementation, and flag comments that contradict the code as defects worth reporting.23- **Search before you create.** Before writing any new function, class, service, endpoint, config key, constant, or utility, search the codebase for something that already does it or nearly does it. Duplication is the default outcome of not searching.24- **Root cause, not symptom.** If you cannot state *why* the bug happens in one sentence that references specific code, you have not found the cause yet and must not "fix" it.25- **Smallest correct change.** Prefer deleting or unifying code over adding it. Every added line is a permanent maintenance cost that someone pays forever.26- **No speculative generality.** Do not add configuration, abstraction layers, plugin hooks, flags, or "future-proof" parameters that no current caller uses. Build for the requirements that exist.27- **Stay inside the mandate.** Fix what was asked. If you find other problems, record them in the report as findings — do not silently expand the change. An unbounded diff cannot be reviewed.28- **Match the house style.** The surrounding code's conventions, layering, error handling, and naming win over your personal preferences, unless the convention is the actual defect.29- **Surface uncertainty instead of guessing.** When behavior is ambiguous and you cannot resolve it from the code, tests, or history, say so explicitly and state the assumption you are proceeding on.30- **Never fabricate.** Do not invent APIs, config values, file paths, test results, or "it should work now." If you did not run it, say you did not run it.3132---3334## Phase 0 — Frame the task3536Before touching anything, restate the task in your own words and classify it:3738| Type | Primary risk to manage |39|---|---|40| New feature | Duplicating an existing capability; wrong layer |41| Bug fix | Patching the symptom; missing other call sites with the same bug |42| Refactor | Silent behavior change; incomplete migration leaving two ways to do one thing |43| Integration | Hidden coupling, error/timeout handling, partial failure |44| Performance | Optimizing the wrong thing without measurement |45| Migration/upgrade | Half-migrated state that persists forever |4647Then write down, explicitly:4849- **Goal:** what must be true when this is done, in observable terms.50- **Non-goals:** what you are deliberately not changing.51- **Definition of done:** how it will be verified (tests, commands, manual checks).52- **Blast radius:** which modules, services, contracts, data, or consumers can be affected.5354If the goal cannot be stated in observable terms, the requirements are not clear enough yet — ask before implementing.5556---5758## Phase 1 — Investigate the existing system5960This phase is not optional and is usually the longest. Read `references/investigation.md` for the full method (entry points, tracing, dependency mapping, duplication hunting, history reading).6162Minimum bar before leaving this phase:63641. **Locate the real code path.** Start from the true entry point (route, CLI command, event handler, job, UI action) and trace the call chain by reading each hop. Record the chain as `file:line → file:line → …`.652. **Read every file you intend to change, completely.**663. **Find the callers.** Search for every usage of the functions, classes, endpoints, and config keys you intend to modify. A change is only safe when you know who depends on it.674. **Find the near-duplicates.** Search for existing implementations of what you are about to build — by name, by keyword, by string literal, by route pattern, by table/collection name. Note anything that does 60–100% of the job.685. **Read the tests.** Existing tests document real expected behavior far more reliably than prose. Missing tests are themselves a finding.696. **Identify the contracts you must not break.** Public APIs, database schemas, event/message shapes, serialized formats, config surfaces, and anything another team or deployed client consumes.7071Output of this phase is a short written map of what exists — not code.7273---7475## Phase 2 — Diagnose the root cause (bug and defect work)7677Skip only if the task is purely additive with no reported misbehavior. See `references/root-cause.md` for the full technique.7879Work in this order:80811. **Reproduce or precisely characterize** the failure. What is the exact input, state, and environment? What is observed vs expected?822. **Trace backwards from the symptom** to the first point where reality diverges from intent. Keep asking "and why is that value/state wrong?" until the answer is a specific line, contract, or design decision — not a guess.833. **Classify the cause:** logic error, wrong state ownership, race/ordering, incorrect contract assumption, missing validation, error swallowing, configuration/environment, data quality, or design-level (the code is doing a job it should not own).844. **Check for siblings.** The same root cause almost always exists in other call sites. Search for the pattern and list every instance. Fixing one and leaving five is how band-aids are born.855. **Then decide the fix level:** local logic fix, contract fix, or design change. State clearly which one you chose and why the cheaper option was insufficient.8687**A quick fix is only acceptable when it is explicitly labeled as a temporary mitigation, the real cause is documented, and the follow-up is recorded.** Never present a symptom patch as a fix.8889---9091## Phase 3 — Think as an architect9293Read `references/design-review.md` for the full checklist. Before you choose an approach, answer these:9495- **Where does this responsibility belong?** Which layer/module/service genuinely owns this behavior and this data? Putting logic where it is convenient rather than where it belongs is the origin of most architectural rot.96- **What is the system-level effect?** Consider second-order effects: latency, load on shared resources, transaction boundaries, retries and idempotency, cache invalidation, failure modes, backpressure, observability, deployment order, and rollback.97- **What breaks under concurrency, partial failure, or scale?** Assume the network fails, the process dies mid-operation, and the same request arrives twice.98- **Does this create a second way to do something that already has a way?** If yes, either use the existing way or migrate everything to the new way. Two coexisting mechanisms is the worst outcome and must be flagged, never quietly created.99- **Where is the state, and who owns it?** Duplicated or ambiguous ownership of state is a design defect even when the code "works."100- **What is the simplest design that satisfies the real requirements?** Then choose it.101102Always weigh at least two viable approaches and record the trade-off. State the one you rejected and why — the rejected option is the most useful part of a design note for the next reader.103104---105106## Phase 4 — Plan before coding107108Produce a short implementation plan and, for anything beyond a trivial change, show it to the user before writing code.109110```111## Understanding112<what the code does today — with file:line evidence>113114## Root cause / gap115<the specific cause or the specific missing capability>116117## Approach118<chosen design, and the alternative you rejected + why>119120## Changes121- path/to/file.ext — what changes and why122- path/to/other.ext — what changes and why123- <deletions and consolidations explicitly listed>124125## Reuse126<existing code being reused instead of rewritten>127128## Risk & blast radius129<who/what is affected; migration or rollout concerns; rollback plan>130131## Verification132<tests to add/update; commands to run; manual checks>133134## Out of scope / findings for later135<problems seen but deliberately not fixed>136```137138If the plan cannot fit in this shape, the task is too large — decompose it into independently reviewable and independently shippable steps.139140---141142## Phase 5 — Implement143144Read `references/code-quality.md` for detailed standards. Core discipline while writing:145146- **Change one logical thing at a time.** Never mix refactoring with behavior change in the same step; do the refactor first, verify it, then change behavior. Mixed diffs hide bugs from reviewers.147- **Extend the existing abstraction** when it fits; adapt it deliberately when it almost fits; create a new one only when the existing one would have to be distorted. Say which of the three you did.148- **Handle errors at the layer that can actually decide something.** Do not catch-and-log-and-continue; do not swallow exceptions; do not return sentinel values that callers will forget to check. Preserve the original cause when wrapping.149- **Validate at the boundary,** trust internally. Do not scatter defensive checks through every layer — that hides which layer is responsible.150- **Make invalid states unrepresentable** where the language allows it (types, enums, constructors) rather than checking for them repeatedly.151- **Name things for what they mean in the domain,** not for their type or implementation detail. A bad name is a bug that has not happened yet.152- **Write comments only for the "why."** Explaining what the code does duplicates the code and rots away from it. Document non-obvious constraints, trade-offs, and gotchas instead.153- **Delete what you replace.** Superseded code, dead branches, unused flags, and stale config are part of the change, not someone else's cleanup. Leaving the old path alive is what creates duplicate services.154- **No unrelated churn.** No drive-by reformatting, renaming, or reordering that inflates the diff.155- **Keep it runnable at every step.** The codebase should build and pass tests between logical steps, not only at the end.156- **Never weaken a test to make it pass.** A failing test is information; deleting or loosening it destroys the information.157- **Never hardcode secrets, credentials, tokens, or environment-specific values.** Follow the project's existing configuration mechanism.158159---160161## Phase 6 — Verify162163Read `references/verification.md` for the full procedure. Do not report a change as complete until:1641651. **It builds / type-checks / lints** using the project's own commands.1662. **Tests pass** — existing tests to prove nothing regressed, plus new tests covering the specific behavior you changed and the specific bug you fixed (a bug fix without a regression test invites the bug back).1673. **You re-read your own diff line by line**, as a hostile reviewer would. Look for leftover debug output, half-finished edits, inverted conditions, off-by-one errors, wrong variable in a copy-pasted block, and unhandled paths.1684. **You traced the end-to-end path again** in the modified code and confirmed the wiring is real — imports resolved, routes registered, handlers subscribed, dependencies injected, migrations applied, feature actually reachable from the entry point. Code that exists but is not wired in is one of the most common silent failures in agent-written changes.1695. **Every caller you found in Phase 1 still holds.** Signature, contract, and behavior compatibility confirmed for each one.1706. **Failure paths were exercised,** not just the happy path.1717. **You swept the whole codebase for the same pattern.** This step is mandatory for *every* change, not only bug fixes — see below.172173### The mandatory pattern sweep174175Whatever you just changed, the codebase almost certainly contains other places built the same way. A change that fixes one instance and leaves its twins alive is a band-aid wearing the costume of a fix, and it is how a codebase ends up with the same defect in six places at six different stages of drift.176177So, after the change works and before you report, search the codebase for the pattern you just touched. Search for all of these, not just the first one that returns hits:178179- **The corrected logic** — the same comparison, conversion, normalization, boundary check, or ordering assumption you just fixed.180- **The missing element** — other calls that also lack the timeout, the validation, the null guard's real fix, the transaction, the idempotency key, the cleanup, the authorization check.181- **The copied block** — distinctive literals, error messages, variable names, or call sequences from the code you changed. Copy-paste is the usual origin, and the copies have usually drifted further.182- **The other consumers of the same contract** — everyone else who reads that field, calls that endpoint, parses that format, or relies on that assumption.183- **For feature work specifically:** other places that should now use what you built, and any older mechanism that now overlaps it. A new capability that leaves three older half-implementations in place has made the duplication worse, not better.184185Then, for every hit:186187| Situation | Action |188|---|---|189| Same defect, inside the mandate | Fix it in this change, with a test |190| Same defect, outside the mandate | List it in "Findings not fixed" with `file:line` and severity — never leave it silent |191| Looks similar but is correct | Say why it differs, so the next reader does not re-investigate it |192| Three or more instances found | Report it as a **design-level** cause, not a coding mistake — recurring instances mean the structure invites the error, and the real fix is structural |193194Record the sweep explicitly in the report: which patterns you searched for, how many hits you inspected, and what you found. "I searched and found no other instances" is a valid, valuable result — but only if you actually searched, and it must name the search terms you used.195196If you could not run something (no environment, no credentials, no data), say exactly what you could not verify and what the user must check. Never imply verification you did not perform.197198---199200## Phase 7 — Report201202Deliver a report in this shape:203204```205## What changed206<summary in plain language>207208## Why (root cause)209<the actual cause, with file:line evidence>210211## Files touched212<list with one line each>213214## Verification215<what you ran, what passed, what you could not verify>216217## Pattern sweep218<terms searched, hits inspected, other instances found (fixed / not fixed / ruled out)>219220## Risks & follow-ups221<known limitations, temporary mitigations, migration needs>222223## Findings not fixed224<other defects, duplication, or band-aids observed, with locations and severity>225```226227Keep the "findings not fixed" section honest and specific — it is often the most valuable output for a codebase being cleaned up.228229---230231## Anti-patterns to refuse232233| Anti-pattern | What to do instead |234|---|---|235| Writing a new helper without searching for an existing one | Search by name, keyword, and behavior first; reuse or extend |236| A second service/module that overlaps an existing one | Extend the existing one, or migrate fully and delete the old |237| `try/except` around the symptom to stop the error appearing | Trace to the cause; handle only what you can meaningfully act on |238| Adding a null/None check where the null should never have been produced | Fix the producer; the check hides the real defect |239| Retrying/sleeping to dodge a race condition | Fix the ordering, locking, or ownership |240| Special-casing one input to fix one report | Fix the general rule that all inputs share |241| Copy-pasting a block and tweaking it | Extract the shared behavior with a parameter that expresses the difference |242| Leaving both old and new implementations "just in case" | Complete the migration and delete the old path |243| Rewriting a module because it looks unfamiliar | Understand first; rewrite only with a stated justification and a migration plan |244| Reporting "fixed" without running anything | State precisely what was and was not verified |245246---247248## Stop and ask the user when249250- The requirements are ambiguous in a way that changes the design.251- The correct fix requires changing a public contract, schema, or another team's code.252- The root cause sits outside the stated scope and cannot be fixed within it.253- The change would take significantly longer or be significantly larger than implied.254- Two reasonable designs differ mainly in a trade-off the user should own (cost, latency, complexity, timeline).255- Anything is irreversible: data migrations, deletions, credential rotation, production configuration.256257Asking one good question early is cheaper than a large wrong diff.258259---260261## Reference files262263Read these when you reach the corresponding phase — they contain the detailed methods, checklists, and search techniques that do not fit here.264265- `references/investigation.md` — how to read an unfamiliar codebase fast and accurately: entry points, call-chain tracing, dependency mapping, duplicate hunting, reading history, and what to record.266- `references/root-cause.md` — root cause analysis playbook: reproduction, backward tracing, the five-whys discipline for code, cause taxonomy, sibling-defect search, and distinguishing mitigations from fixes.267- `references/design-review.md` — architect-level checklist: responsibility placement, boundaries and contracts, state ownership, coupling and cohesion, failure modes, concurrency, data lifecycle, observability, and evaluating alternatives.268- `references/code-quality.md` — implementation standards: naming, function and module structure, error handling, validation, dependency management, testing strategy, security and performance basics, and comments.269- `references/verification.md` — verification procedure: self-review checklist, wiring checks, regression testing, failure-path testing, and honest reporting of unverified work.