This repository follows Code Complete in the sense of Steve McConnell: apply disciplined software construction practices that reduce defects, improve readability, and produce robust code under real-world constraints.
All code generation, edits, and reviews must optimize for:
- low-defect construction
- readable and intention-revealing code
- controlled complexity
- defensive programming where appropriate
- strong routine and class design
- practical correctness over style theater
This file is a binding engineering policy: MUST is binding, SHOULD is a strong default, and MUST NOT is forbidden.
Construction quality is not accidental.
When uncertain, choose the option that:
- lowers defect probability
- makes the code easier to inspect and reason about
- reduces control-flow complexity
- uses data and routines clearly
- protects the program against invalid states and misuse
Do not optimize for cleverness, minimal keystrokes, or fashionable idioms at the cost of clarity.
- Write code primarily for human readers.
- Favor clarity, locality, and explicitness over trickiness.
- Keep control flow simple and visible.
- Make correctness easier to achieve than incorrectness.
- Use conventions consistently.
- Do not treat construction as isolated typing; verify that requirements, architecture, major risks, and coding conventions are clear enough for the change.
- Resolve major construction decisions before large implementation work: language constraints, error policy, data representation, reuse strategy, integration approach, and testing approach.
- Use upstream uncertainty as a reason to build a small validated slice, not as an excuse for speculative code.
- Keep the software metaphor or design model only if it helps make concrete construction decisions.
- Measure twice before cutting when an early decision will be expensive to reverse.
- For complex routines, sketch the routine in precise pseudocode or comments before filling in details.
- Refine pseudocode until it names the real steps at a consistent abstraction level.
- Convert clear pseudocode into code and keep only comments that still add intent, constraints, or rationale.
- Do not use pseudocode as a substitute for understanding the algorithm.
- Routines should have one clear purpose.
- The routine name should describe the result or action precisely.
- Keep the interface as small as practical.
- Avoid long parameter lists and flag arguments.
- Separate setup, validation, computation, and side effects when they are conceptually different.
- Return values should be meaningful and hard to misuse.
- Prefer guard clauses and straightforward structure over deeply nested logic.
Anti-patterns (MUST NOT):
- routines that do several unrelated things
- routines whose names describe implementation detail instead of purpose
- many hidden side effects
- boolean parameters that switch routine mode
- Use names that reveal purpose and meaning.
- Keep variable scope as small as practical.
- Initialize variables deliberately.
- Prefer named constants or stable values where a variable is not meant to change.
- Avoid magic numbers and unexplained sentinel values.
- Use stronger data types when primitives hide meaning.
Anti-patterns (MUST NOT):
- reused loop/index/temp variables beyond their purpose
- long-lived mutable locals carrying many meanings
- values whose units or semantics are unclear
- Choose data types that make invalid or ambiguous values harder to represent.
- Name constants for magic values, units, bounds, and sentinel meanings.
- Use booleans only for true binary meanings; replace flag fields with clearer states when needed.
- Use enumerations or named alternatives when a value belongs to a closed set.
- Use arrays, records, maps, and tables only where their shape communicates the data meaning.
- Encapsulate unusual data structures behind routines or types that reveal purpose.
- Keep units, ranges, precision, encoding, and ownership visible near the data they affect.
- Prefer the simplest control flow that expresses the logic.
- Keep nesting shallow when possible.
- Replace complicated boolean logic with named predicates or clearer structure.
- Use case/switch constructs only when they improve clarity.
- Eliminate impossible paths and dead branches.
- Avoid surprising exits unless they clarify the routine.
Anti-patterns (MUST NOT):
- deeply nested conditionals
- complicated loop exits with hidden state changes
- control flow dependent on side effects in expressions
- clever one-liners that obscure the logic
- Organize straight-line code so dependencies appear before use and related statements stay together.
- Keep conditionals positive and direct when possible.
- Put the normal path where readers can find it quickly.
- Use loops with clear initialization, termination, and update rules.
- Keep loop bodies focused; extract work when a loop hides several responsibilities.
- Avoid unusual control structures unless they are clearer than ordinary alternatives.
- Use table-driven methods when repeated branching is stable and the table can be validated.
- Validate inputs at trust boundaries.
- Use assertions or invariant checks where programmer assumptions matter.
- Distinguish between recoverable conditions and programming errors.
- Fail in a way that preserves diagnosability.
- Do not silently continue from corrupted or impossible state.
Anti-patterns (MUST NOT):
- assuming all callers are correct
- burying invalid state until it causes distant failures
- swallowing exceptions without context
- Handle errors at the right level of abstraction.
- Preserve useful context.
- Do not let error handling dominate the normal path.
- Standardize similar failure handling.
- Prefer explicit, well-understood failure semantics over ad hoc conventions.
- Prefer data-driven logic over long repeated condition chains when the mapping is stable and explicit.
- Use tables or maps for configuration-like decisions.
- Keep the structure obvious and validated.
- Do not hide complex logic in inscrutable data encodings.
- Each class or module should own a focused responsibility.
- Separate interface from implementation.
- Hide representation and incidental detail.
- Keep classes cohesive.
- Reduce coupling through clear contracts and limited knowledge of internals.
Anti-patterns (MUST NOT):
- god classes
- modules with mixed persistence, formatting, business logic, and integration concerns
- public surfaces that expose internal bookkeeping
- Treat rising complexity as a defect risk.
- Prefer simple code over clever code.
- Break apart large or tangled routines and modules.
- Remove duplication that multiplies maintenance effort.
- Choose designs that reduce the amount a maintainer must keep in working memory.
- Be explicit about routine assumptions.
- Encode important invariants close to the code they protect.
- Keep contracts simple and testable.
- Use assertions for programmer mistakes, validation for external input, and domain errors for expected business failures.
- Comments should explain intent, rationale, contracts, and non-obvious facts.
- Do not comment obvious code instead of improving it.
- Keep comments accurate or delete them.
- Prefer self-documenting structure first, comments second.
- Be consistent within the codebase.
- Use formatting, naming, and file structure to support readability.
- Standardize common idioms so readers do not need to relearn style per module.
- Prefer a shared convention over local personal taste.
- Build in small, verifiable increments.
- Integrate frequently enough to surface conflicts and misunderstanding early.
- Keep partial work from rotting in long-lived isolation.
- Review and improve code as part of construction, not only after it.
- Use reviews, inspections, pair work, tests, and static checks according to the risk of the code.
- Treat debugging as diagnosis: reproduce, isolate, explain, fix, and verify rather than guessing.
- Fix the root cause when practical, not only the symptom.
- Add tests around defects so the same failure is easier to detect next time.
- Refactor when structure hides intent, duplicates knowledge, or raises defect probability.
- Keep refactoring separate from behavior changes when that improves reviewability.
- Do not tune performance until the requirement and evidence justify it.
- When tuning is justified, measure before and after, and keep clarity unless the tradeoff is explicit.
- Integrate frequently enough to expose construction conflicts early.
- Use programming tools, scripts, debuggers, profilers, editors, and build automation to reduce error-prone manual work.
- Keep layout and style consistent enough that readers can focus on meaning.
- Prefer self-documenting code, but add documentation where the code cannot express intent, constraints, or usage.
- Treat personal discipline, curiosity, and ability to withstand careful review as part of construction quality.
When reviewing code, actively look for:
- unclear names
- weak routine boundaries
- long parameter lists
- unnecessary nesting
- hidden side effects
- poor defensive checks at trust boundaries
- duplicated logic
- confusing control flow
- god classes or mixed responsibilities
- comments compensating for poor structure
- dense tricks that are hard to inspect
- compressed expressions that save lines but increase interpretation cost
- one routine doing several phases and concerns
- long signatures with many unrelated parameters
- no validation at trust boundaries
- no checks around critical assumptions
- silent fallback from impossible state
- obvious comments over bad code
- stale comments that mislead
- arbitrary naming and formatting changes
- module-specific mini dialects inside one codebase
When generating code, default to:
- clear names
- focused routines
- explicit data meaning
- simple control flow
- defensive checks at boundaries
- cohesive classes/modules
- consistent style
Avoid by default:
- dense clever code
- broad god objects
- fragile hidden assumptions
- unnecessary complexity in loops and conditionals
- comments where better names or decomposition would do
- Test routine behavior around normal, boundary, and invalid inputs.
- Test defensive checks where boundary validation matters.
- Keep tests aligned with routine contracts.
- Test complex data-driven logic with representative tables and edge cases.
Before finalizing any change, verify:
- Are names clear and intention-revealing?
- Are routines focused and reasonably small?
- Is control flow straightforward?
- Are trust boundaries defended?
- Are contracts and invariants explicit enough?
- Did we reduce or at least not increase complexity?
- Are classes/modules cohesive?
- Did we avoid cleverness that harms inspection?
- Are comments used only where they add value?
- Is the style consistent with the rest of the codebase?
If any answer is no, revise before shipping.
When uncertain, choose the option that:
- lowers defect risk
- improves readability
- simplifies control flow
- strengthens defensive correctness
- keeps the code easier to inspect and maintain
Write code that would stand up to careful review.