Files
atelier/review/anti-patterns.md
T
Jon Chery 9ebc9c8868 docs(milestone): complete v0.3 — GitOps+Operators/AI-ML/i18n/Compliance
---ci---
project: atelier
phase: 6
milestone: v0.3
status: complete
requirements:
  covered: [ATELIER-60..91]
  partial: []
---/ci---
2026-08-05 03:45:38 +00:00

13 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

Infrastructure as Code

Anti-Pattern Breaches Why
Unpinned provider (source without version) P5 Version Everything Unversioned drift
terraform apply without a read plan P4 Plan Before Apply Unreviewed mutation
Local state in a shared environment P8 Remote State with Locking No lock = corruption
Hardcoded secret in HCL P10 Secrets Never in Code Committed secret
Copy-pasted block instead of a module P6 Modules Compose Bug duplicated
Manual change to a managed resource P9 Drift is Recoverable Unreconciled drift
Admin credentials in CI P7 Least Privilege Providers Overbroad grant
Committed terraform.tfstate P3 State is Truth, P10 Secret-bearing artifact in repo

Kubernetes

Anti-Pattern Breaches Why
Bare pod (no controller) P2 Pods are Mortal No recovery/scale
No resource requests in prod P4 Requests and Limits BestEffort, first evicted
Liveness probe checks a dependency P5 Probes Drive Health Cascade restart
cluster-admin bound to a workload P7 RBAC by Intent Overbroad grant
:latest image tag in prod P5 Version Everything Unversioned drift
emptyDir for data that must persist P8 Storage is Explicit Data lost on pod death
Secrets baked into the image P9 Config and Secrets Separate No rotation without rebuild
default namespace in prod P6 Namespaces Bound Blast Radius No blast boundary
Shared PVC across StatefulSet replicas P8 Storage is Explicit Concurrent write corruption
Delete reclaim policy on prod storage P8, P5 Reversibility PVC delete = data delete

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

v0.2 Chaos Anti-Patterns (from IDEATE-13, IDEATE-14)

Anti-Pattern Breaches Why
Orphaned P-rule (a domain principle with no matrix row) matrix completeness, C6 Breaks the conflict-resolution arbiter; the rule has no core trace
Deployable example artifact (standalone .tf/.yaml under examples/) PROJECT.md "no runtime code", D-025 Violates the docs-only contract; examples must be .md with fenced code
Unlisted v0.2 doc (new doc not added to MANIFEST) manifest rule Not part of the framework by definition

v0.3 Chaos Anti-Patterns (from IDEATE-20, IDEATE-24, IDEATE-25, IDEATE-27)

These are named, cross-cutting violations specific to the v0.3 domains. Reject on sight.

Anti-Pattern Breaches Why
GitOps push-pattern (external CI pushes manifests to the cluster instead of an in-cluster agent pulling from git) gitops P3 Pull, Don't Push; C1, C4 Inverts the source-of-truth flow; requires push credentials into the cluster; breaks the reconciliation model (IDEATE-24, D-042)
i18n LTR-only assumption (layout assumes left-to-right; no dir attribute, physical CSS properties only) i18n P6 Text Direction is a Layout Primitive; C1, C4 Disqualifying for RTL/Bidi users; locale-correctness violation (IDEATE-25, D-043)
AI/ML orphan-model (a deployed prediction endpoint whose model has no lineage trace — no record of training run, dataset, or version) ai-ml P3 Lineage is Traceable End-to-End; C7, C1 Unreviewable, unrollbackable; the model is an unattributed artifact (IDEATE-27, D-045)
Compliance mutable audit log (audit records can be edited or deleted by an operator) compliance P1 Audit Logs are Append-Only; C1, C5 Destroys the audit trail; the audit log's value is immutability — mutation is itself an incident

v0.3 Deployable Artifact Types (IDEATE-20, D-020)

The following standalone file types are forbidden under examples/ and elsewhere in the framework. Examples are .md files with fenced code only.

Forbidden standalone artifact Belongs in Why
.po / .pot resource files fenced code in examples/good//examples/bad/*.md Runtime localization artifact; violates docs-only contract
.rego / .cedar / .sentinel policy files fenced code in examples/*.md Runtime policy artifact; violates docs-only contract
Model artifacts (.pkl, .onnx, .pt, .h5, .safetensors) fenced code + prose in examples/*.md Runtime model artifact; violates docs-only contract
Signed manifests as standalone files (.sig, .att, .intoto.jsonl) fenced code in examples/*.md Runtime attestation artifact; violates docs-only contract
Standalone .yaml / .tf / .sh fenced code in examples/*.md (Carried forward from v0.2) Runtime deployable artifact

v0.3 Domain-Specific Anti-Patterns

GitOps + Operators

Anti-Pattern Breaches Why
Push-based deploy (external CI kubectl apply into the cluster) P3 Pull, Don't Push Inverts the model; requires push credentials; bypasses reconciliation
Manual kubectl apply/kubectl edit on a GitOps-managed resource P8 Reconcile, Don't Mutate by Hand Unreconciled drift; the next loop overwrites it — silent and unattributed
cluster-admin GitOps robot (controller bound to cluster-admin) P10 Least Privilege Reconciliation Overbroad grant; blast radius = entire cluster
No sync-failure notification (silent drift on health degradation) P9 Failure is Observable and Surfaced Silent drift is the bug the loop was supposed to surface

AI / ML

Anti-Pattern Breaches Why
Unreproducible training run (unpinned data, code, config, or environment) P1 Reproducibility is the First Class Unreviewable; cannot debug, cannot rollback
"Use the latest model" (serving points at model:latest instead of a pinned version) P5 Models are Versioned Artifacts Unversioned drift; rollback undefined
Notebook in production (training/serving flow is a Jupyter notebook) P9 Pipelines Compose, Notebooks Don't No contracts, no composition, no reproducibility
Orphan model (deployed prediction with no lineage trace) P3 Lineage is Traceable End-to-End Unattributed artifact; cannot trace to data/code (IDEATE-27)

i18n

Anti-Pattern Breaches Why
Inline string concatenation ("Hello, " + name + "!" in code) P3 Resources are External, Not Inline Not extractable; breaks translations; word-order differs per locale
if (n == 1) plural branching (hand-rolled plural logic) P4 Plural and Gender are Parameterized Wrong for Arabic, Russian, Polish; ICU MessageFormat handles plurals
LTR-only layout (no dir attribute, physical CSS left/right) P6 Text Direction is a Layout Primitive Disqualifying for RTL/Bidi (IDEATE-25)
Hand-rolled date/number formatter (new Date().toString(), manual string formatting) P5 Formatting is Locale-Aware Locale-incorrect; ignores ICU/CLDR

Compliance

Anti-Pattern Breaches Why
Mutable audit log (operator can UPDATE/DELETE audit records) P1 Audit Logs are Append-Only Destroys the audit trail; mutation is itself an incident
Shared/generic identity in audit (admin or system as the actor for all actions) P7 Identity is Attributable No attribution; no accountability; cannot investigate
Secret leaked in audit log (request body or token captured in an audit event) P9 Secrets and Sensitive Data are Redacted in Audit Audit log becomes a secret exfiltration channel
Manual evidence assembly at audit time (scramble to collect logs/scans/attestations on demand) P6 Evidence is Collected Continuously Audit-unready; evidence gathered under pressure is incomplete and unreliable