Senior Dev Principles
Structure and complexity layer. code-style-defaults governs the form of the output; python-native governs Python stdlib usage; this skill governs how code is structured and how fast it runs. Every rule is a requirement, not a suggestion.
Precedence: user's explicit instruction > convention of the file being edited > this list.
1. Algorithmic complexity — reason before writing
Mandatory for algorithmic code, hot paths, and anything touching unbounded or user-controlled input size. Skip for glue code, CRUD handlers, and transforms over known-small data.
| Problem | Naive | Target | Technique |
|---|---|---|---|
| Membership test | O(n) | O(1) amort. | set / dict |
| Find duplicates | O(n²) | O(n) | hash set |
| Pair matching | O(n²) | O(n) | hash map |
| Sorted lookup | O(n) | O(log n) | binary search |
| Shortest path (single-source, non-negative weights) | O(V²) | O((V+E) log V) | Dijkstra + min-heap; for negative edges use Bellman-Ford, or Johnson for all-pairs |
| Substring search | O(nm) | O(n+m) | KMP (worst-case O(n+m)); Rabin-Karp (expected O(n+m), worst-case O(nm) on hash collisions) |
| Top-K elements | O(n log n) | O(n log k) | min-heap of size k |
| Range sum queries | O(n) each | O(1) each | prefix sum array |
| Repeated subproblem | O(2ⁿ) | states × transition cost | memoization / DP (e.g. matrix-chain O(n³), 0/1 knapsack pseudo-polynomial O(nW)) |
- Do NOT use nested loops when a hash map flattens them.
- Do NOT sort inside a loop when one sort outside suffices.
- Do NOT use
in listmembership when n is unbounded — useset/dict. - Do NOT accept O(n²) or worse on unbounded input without stating why in one line.
- DO note complexity in a comment only when non-obvious (recursive DP, custom structures, early exits) — never on obvious linear scans.
2. Structure
- Do NOT put two reasons-to-change in one unit — DB access + business rules + serialization is three units.
- Do NOT split a unit that reads top-to-bottom cohesively just to make files smaller.
- Do NOT create names nobody would search for (
OrderHelperUtils,ProcessingManagerImpl) — if the split forces one, the split is wrong. - Do NOT judge by size: a 50-line cohesive function is fine; a 30-line file mixing two domains is not. Split concerns, keep cohesion.
- Do NOT inline a literal that encodes policy —
MAX_RETRIES, not3. DO inline intrinsic literals (bytes[0],len(parts) == 2). - Do NOT bury I/O inside logic when tests exist — pure functions where natural, I/O at the edges.
- Do NOT restructure working code purely to enable tests nobody will write.
3. Per-language
Python lives in python-native.
TypeScript
constby default,letonly on mutation, nevervar.- Explicit return types on exported functions.
strict: true;unknown+ narrowing overany.async/awaitover raw.thenchains.
C
- Every allocation has an owner and a matching free; verify with Valgrind or ASan.
- No implicit
switchfallthrough —breakor/* fallthrough */. size_tfor sizes and indices; never mix signed/unsigned.- Header guards on every
.h.
C++
- RAII: resources owned by objects, never managed manually.
unique_ptr/shared_ptrover raw owning pointers.conston non-mutating methods;const&for non-trivial parameters.std::vector/std::arrayover raw arrays; Rule of Zero;expliciton single-argument constructors.
SQL
- Explicit column lists, never
SELECT *in production paths. - Consider an index for new WHERE/JOIN columns; do NOT over-index write-heavy tables.
- Run
EXPLAINon queries that will scan large tables.
Self-review before presenting
- State each unit's purpose in one sentence — if you can't, restructure.
- Is the complexity acceptable for realistic input sizes?
- Edge cases handled, or explicitly out of scope?
- Correct > clear > efficient > maintainable — in that order.