Refactoring, sizing a diff, or tempted to add abstractions, layers, or signal threading.
Bias to deletion and the smallest change that solves the problem.
Make the smallest change that solves the problem. Fewer lines beat "elegant" boilerplate.
Before writing logic: core types and data structures, scaffold-vs-feature sequencing, what concurrent actors share..
Ask "does every subsequent phase benefit from this existing?"
Integrating a new requirement into an existing design.
Redesign as if it had been foundational from day one.
Ask: "if we were writing this from scratch with this new requirement, what would we build?"
Two or more fixes that share one premise have failed the same gate.
Write the premise down and test it directly before you write another fix that assumes it.
Do not start the next fix before the premise is written down and tested.
Sequencing an addition, refactor, or rewrite.
Remove dead weight first, then build on the simpler base.
When a reference has no novel content, delete it rather than leaving a stub
Reviewing or shaping code that's hard to trace.
Count layers and hidden state, collapse one-caller wrappers, shrink mutable scope.
can a new reader answer "where does X come from?" and "what can change X?" in under 30 seconds? If not, cut layers or cut state.
Planned rewrites and migrations with explicit phase boundaries.
Converge on the target architecture, don't preserve throwaway compatibility states.
Intermediate breakage is acceptable when it is planned, scoped, and reversible
Product, UX, or feature-scope tradeoffs.
Choose user delight over implementation convenience.
The engineer who maintains the code next is a user too.
A novel interaction or architectural decision with no precedent.
Build 2-3 competing prototypes and compare before committing.
It also applies to product design decisions where user experience depends on feel, not logic.
Any non-trivial work.
Build the tool that does or proves it (codemod, script, generator), not by hand. The tool is the artifact a reviewer reruns.
If you cited it and there is no codemod, script, generator, or delegate skill in the diff, you didn't apply it.
Writing stateful logic, or code that branches a lot or repeats a shape assumption across files.
Encode the domain in a structure (state machine, typed model, table or registry, reducer, boundary, the right collection) instead of scattered conditionals.
The sign that you skipped this is a new feature that grows an existing if/else chain by one more branch, or a second boolean that must stay in sync with the first.
Wiring validation, error handling, or framework adapters.
Guards at system boundaries, trust internal types, keep business logic pure.
"Is this data crossing a system boundary right now?" If not, validation is redundant.
Designing types or a signature in any typed language.
Make illegal states unrepresentable, brand primitives, parse external data at boundaries.
If two arguments share a primitive type but mean different things, brand them.
Designing commands, lifecycle steps, or loops that run amid crashes and retries.
Converge to the same end state.
If any answer is "it depends on what state was left behind," the operation needs a reconciliation step.
Introducing a new internal API while old callers exist.
Migrate and delete in one wave.
Update tests to assert the new contract, and delete tests that only protect pre-refactor implementation details
Concurrent actors might write the same file, branch, key, or object.
Eliminate the sharing first.
Instructions and conventions are not concurrency control.
After a task, before declaring done.
Verify against the real artifact, not a proxy or "it compiles".
When verification fails, suspect the observation method before suspecting the system
Debugging.
Trace each symptom back to the first place the system went wrong and fix it there. A guard is a fix only when the state it handles is legitimate.
If a workaround needs a paragraph-long comment to justify it, the code is wrong. Fix the code, not the comment.
Multi-step work (sweeps, migrations, runs of similar edits) and how you stack commits and PRs.
Break work into small units that each end in a check, verify each before the next, and order delivery so the sequence proves itself.
When a lever does the edits, the per-unit check is nearly free. Run it anyway.
Writing, changing, or keeping a test.
Assert what the code's users can observe, so the test fails when that behavior breaks and keeps passing when only the internals change.
Keep a test that catches the first edit and survives the second. Rewrite or delete the rest.
Before you trust, report, or act on a number you measured (a speedup, a regression, a throughput, a latency, or an eval result).
Find what limits it, and rule out that it measured something other than the work you think.
If you cannot say why the number is not twice as good, you do not know what you measured.
Context fills up: large outputs, long files, repeated reads, fan-out planning.
Route bulk to subagents, keep summaries in the main thread.
Limit files per phase, set turn budgets, account for mechanism costs.
Tempted to ask "should I do X?" on reversible work.
Proceed, present the result, let the human course-correct.
Irreversible actions (force-push, delete production data, send external messages) still require confirmation.