Files
atelier/review/anti-patterns.md
T
Jon Chery 496303471d docs(milestone): complete v0.1 — initial framework
---ci---
project: atelier
phase: 7
milestone: v0.1
status: complete
phase_role: final
milestone_complete: true
requirements:
  covered: [ATELIER-01, ATELIER-02, ATELIER-03, ATELIER-04, ATELIER-05, ATELIER-06, ATELIER-07, ATELIER-08, ATELIER-09, ATELIER-10, ATELIER-11, ATELIER-12, ATELIER-13, ATELIER-14, ATELIER-15, ATELIER-16, ATELIER-17, ATELIER-18, ATELIER-19, ATELIER-20, ATELIER-21, ATELIER-22, ATELIER-23, ATELIER-24, ATELIER-25, ATELIER-26, ATELIER-27, ATELIER-28, ATELIER-29, ATELIER-30, ATELIER-31, ATELIER-32, ATELIER-33, ATELIER-34, ATELIER-35]
  partial: []
ship:
  milestone: v0.1
  type: NFR
  tag: v0.0.7
  merge: milestone/v0.1-atelier -> main
  release: https://git.cloudinit.dev/cloudinit-bot/atelier/releases/tag/v0.0.7
---/ci---

Milestone v0.1 — Initial Framework (NFR, complete).
8 core principles (C1-C8), 11 domains, 110 domain principles, 27 derived docs, 4 good + 3 bad examples, 4 language docs, full matrix, 3 review docs.
All 35 requirements covered. 7 patches (v0.0.0 pre-execution through v0.0.7 final). v0.0.7 IS the v0.1.0 milestone release.
2026-08-05 00:36:55 +00:00

5.7 KiB
Raw Blame History

Anti-Patterns

A catalog of violations. Each entry names the principle it breaches. Use this to recognize and reject patterns on sight.

How to Use

When you see a pattern listed here, it is a defect. Cite the principle it violates and require a fix. These are not "to be reviewed later"; they are rejected on sight.

Core Anti-Patterns (C1C8)

Anti-Pattern Breaches Why
Code that "mostly works" C1 Correctness Mostly correct is incorrect
function doStuff() C2 Clarity Name reveals nothing
A 500-line function C3 Simplicity Complexity is a liability
Config in a distant repo, read silently C4 Locality Coupling you cannot see
A migration with no down C5 Reversibility Irreversible bet
A component reading global state implicitly C6 Composability Hidden dependency
A service with no logs C7 Observability Cannot debug what you cannot see
Loading all records into memory C8 Economy Unbounded = OOM

Domain Anti-Patterns

UI/UX

Anti-Pattern Breaches Why
Image without alt P2 Accessibility Disqualifying
"Delete" with no confirmation P5 Forgiveness Irreversible surprise
color: #3b82f6 in a component P8 Consistency (via tokens) Bypasses design system
"Submit" on a delete button P3 Clarity Wrong verb
Layout shift on image load P7 Hierarchy / CLS Visual instability

API

Anti-Pattern Breaches Why
/getUsers (verb in URL) P2 Clarity Resources are nouns
200 with an error body P9 Error Transparency Status code lies
500 with a stack trace P8 Security, P9 Information leak
No Idempotency-Key on a POST P6 Idempotency Retry is unsafe
10MB response by default P7 Performance Unbounded payload

Security

Anti-Pattern Breaches Why
eval() of any string P4, P5 Code injection
Hardcoded API key in source P9 Secret Hygiene Committed secret
catch (e) {} (swallow) P7, P8 Silent failure, fail-open
md5 for password hashing P6 Crypto Broken primitive
Open CORS * in production P1, P10 Zero trust violated
chmod 777 P2 Least Privilege Maximum privilege
Logging the request body P9 Secret Hygiene Token leak

Data

Anti-Pattern Breaches Why
VARCHAR for a UUID P7 Type Fidelity Wrong type
No FOREIGN KEY P3, P9 Unenforced relationship
FLOAT for money P7, P1 Floating point error
is_deleted without filtering P8 Lifecycle Soft-delete leak
SELECT * P10 Performance Unbounded columns

Testing

Anti-Pattern Breaches Why
Test that cannot fail P10 No Test Theater Not a test
Date.now() in a fixture P3 Determinism Flaky
Shared fixture mutated across tests P2 Independence Order-dependent
500 e2e tests, 50 unit P4 Fast Feedback Inverted pyramid
name: "test" fixture P7 Realism Hides bugs

Performance

Anti-Pattern Breaches Why
N+1 query in a loop P3 Complexity O(N) queries
No timeout on HTTP call P4, P8 (concurrency) Hang forever
Cache with no invalidation P5 Caching Stale forever
Unbounded in-memory sort P4 Resource Bounds OOM
Optimization without measurement P1 Measure First Guesswork

Observability

Anti-Pattern Breaches Why
console.log("here") P1 Structured Not queryable
user_id as a metric label P4 Cardinality Unbounded bill
Average latency only P8 SLO Hides the tail
No trace_id propagation P2 Correlation Cannot trace
Logs without request_id P3 Context No correlation

Errors

Anti-Pattern Breaches Why
catch (e) { return null } P2 Fail Loudly Silent failure
throw new Error("error") P3 Fail Specifically Generic
return null for "not found" P1 Errors are Data Conflates absence with error
Retry without backoff P5, P8 Retry storm
throw in a recovery path P6 Fail fast in wrong place

Documentation

Anti-Pattern Breaches Why
Doc with no examples P3 Examples Incomplete
Stale doc (wrong, not updated) P4 Currency Worse than no doc
Unlisted doc (not in MANIFEST) (framework rule) Not part of framework
No audience statement P2 Audience Who is this for?

Concurrency

Anti-Pattern Breaches Why
Shared mutable state, no lock P1 Immutability Race condition
Unbounded queue P9 Bounded Queues OOM
channel.send() with no timeout P8 Timeout Hang
Mutex held across I/O P3 Lock Scope Lock too long
Spawned work with no cancellation P7 Cancellation Orphaned work

DevOps

Anti-Pattern Breaches Why
Manual deploy script P2 Automation Not repeatable
No rollback path P4 Rollback Irreversible deploy
Big-bang deploy P5 Progressive All-or-nothing
Rebuild per environment P7 Immutability Different artifacts
Snowflake server P1, P6 Not reproducible

Cross-Cutting Anti-Patterns

Anti-Pattern Breaches Why
"I'll add tests later" C1 (no proof of correctness) Later never comes
"It's just a prototype" C5 (irreversible by default) Prototypes go to prod
Copy-paste code C6 (no composition) Bug duplicated
God object C3, C6 One thing, many things
Leaky abstraction C6, C2 Hidden coupling