feat: add KISS and task-discipline contracts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-03-06 18:07:47 +03:00
parent a38c35ce2d
commit 0e61346d20
2 changed files with 77 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
# Contract: Keep It Simple
Version: 1.0
## Principle
Working solutions do not need to be interesting.
Prefer the simplest solution that correctly solves the problem. Complexity must be justified by a real, present requirement — not by anticipation of future needs or desire to use a particular technique.
## Rules
- Choose boring technology. A well-understood, dull solution beats a clever one.
- Do not introduce abstractions, patterns, or frameworks before they are needed by at least two concrete use cases.
- Do not design for hypothetical future requirements. Build for what exists now.
- Prefer sequential, readable code over clever one-liners.
- If you can delete code and the system still works, delete it.
- Extra configurability, generalization, and extensibility are costs, not features. Add them only when explicitly required.
## Anti-patterns
- Adding helpers or utilities for one-time operations.
- Wrapping simple logic in interfaces "for testability" when a direct call works.
- Using a framework or library to solve a problem the standard library already handles.
- Writing error handling, fallbacks, or validation for scenarios that cannot happen.
- Refactoring working code because it "could be cleaner."
## Bulletproof features
A feature must be correct by construction, not by circumstance.
Do not write mechanisms that silently rely on:
- another feature being in a specific state,
- input data having a particular shape that "usually" holds,
- a certain call order or timing,
- a global flag, ambient variable, or external condition being set upstream.
Such mechanisms are thin: they work only when the world cooperates. When any surrounding assumption shifts, they break in ways that are hard to trace. This is the primary source of bugs.
**Design rules:**
- A feature owns its preconditions. If it requires data in a certain state, it must enforce or produce that state itself — not inherit it silently from a caller.
- Never write logic that only works if a sibling feature runs first and succeeds. If coordination is needed, make it explicit (a parameter, a return value, a clear contract).
- Avoid implicit state machines — sequences where operations must happen in the right order with no enforcement. Either enforce the order structurally or eliminate the dependency.
- Prefer thick, unconditional logic over thin conditional chains that assume stable context. A mechanism that always does the right thing is more reliable than one that does the right thing only when conditions are favorable.
A feature is done when it is correct on its own, not when it is correct given that everything else is also correct.
## Checklist before committing
1. Could this be done with fewer lines without losing clarity?
2. Does every abstraction here have more than one caller?
3. Is any of this code handling a case that cannot actually occur?
4. Did I add anything beyond what was asked?
If the answer to any of 14 is "yes," simplify before committing.

View File

@@ -0,0 +1,21 @@
# Contract: Task Discipline
Version: 1.0
## Principle
Finish before switching. A task is not done until it reaches a logical end.
## Rules
- Do not start a new task while the current one is unfinished. Switching mid-task leaves half-done work that is harder to recover than if it had never been started.
- If a new idea or requirement surfaces during work, note it and address it after the current task is complete.
- "Logical end" means: the change works, is committed, and leaves the codebase in a coherent state — not just "the immediate code compiles."
- Do not open new files, refactor adjacent code, or fix unrelated issues while implementing a specific task. Stay focused on the defined scope.
- If the current task is blocked, resolve the blocker or explicitly hand off — do not silently pivot to something else.
## Anti-patterns
- Starting a refactor while in the middle of a bug fix.
- Leaving a feature half-implemented because something more interesting came up.
- Responding to a new requirement by abandoning the current one without documenting what was left unfinished.