@neikyun/ciel 6.11.2 → 6.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/assets/.claude/agents/ciel-critic.md +71 -12
  2. package/assets/.claude/agents/ciel-explorer.md +59 -18
  3. package/assets/.claude/agents/ciel-improver.md +6 -3
  4. package/assets/.claude/agents/ciel-researcher.md +85 -25
  5. package/assets/.claude/hooks/block-destructive.sh +2 -2
  6. package/assets/.claude/hooks/check-test-first.sh +2 -2
  7. package/assets/.claude/hooks/memory-bootstrap.sh +0 -0
  8. package/assets/.claude/hooks/memory-engine.py +82 -15
  9. package/assets/.claude/hooks/post-tool-write.sh +32 -0
  10. package/assets/.claude/hooks/pre-agent-gate.sh +11 -6
  11. package/assets/.claude/hooks/pre-compact.sh +18 -0
  12. package/assets/.claude/hooks/pre-tool-write.sh +56 -31
  13. package/assets/.claude/hooks/session-start.sh +22 -1
  14. package/assets/.claude/hooks/session-version-check.sh +1 -1
  15. package/assets/.claude/hooks/stop.sh +104 -0
  16. package/assets/.claude/hooks/subagent-stop.sh +54 -0
  17. package/assets/.claude/hooks/track-file.sh +2 -2
  18. package/assets/.claude/hooks/user-prompt-submit.sh +11 -15
  19. package/assets/.claude/settings.json +18 -4
  20. package/assets/AGENTS.md +1 -1
  21. package/assets/CLAUDE.md +103 -175
  22. package/assets/commands/ciel-audit.md +58 -399
  23. package/assets/commands/ciel-create-skill.md +24 -38
  24. package/assets/commands/ciel-eval.md +25 -37
  25. package/assets/commands/ciel-init.md +36 -126
  26. package/assets/commands/ciel-status.md +22 -19
  27. package/assets/commands/ciel-update.md +20 -39
  28. package/assets/platforms/opencode/.opencode/agents/ciel-researcher.md +71 -895
  29. package/assets/platforms/opencode/.opencode/commands/ciel-audit.md +58 -296
  30. package/assets/platforms/opencode/.opencode/commands/ciel-create-skill.md +24 -46
  31. package/assets/platforms/opencode/.opencode/commands/ciel-eval.md +25 -45
  32. package/assets/platforms/opencode/.opencode/commands/ciel-init.md +36 -131
  33. package/assets/platforms/opencode/.opencode/commands/ciel-status.md +22 -24
  34. package/assets/platforms/opencode/.opencode/commands/ciel-update.md +20 -40
  35. package/assets/platforms/opencode/AGENTS.md +4 -4
  36. package/assets/rules/security.md +30 -0
  37. package/assets/rules/testing.md +23 -0
  38. package/assets/skills/agile/SKILL.md +42 -0
  39. package/assets/skills/alerting/SKILL.md +55 -0
  40. package/assets/skills/api-design/SKILL.md +46 -0
  41. package/assets/skills/appsec/SKILL.md +43 -0
  42. package/assets/skills/architecture/SKILL.md +74 -0
  43. package/assets/skills/backend/SKILL.md +41 -0
  44. package/assets/skills/backup-recovery/SKILL.md +42 -0
  45. package/assets/skills/caching/SKILL.md +44 -0
  46. package/assets/skills/cdn/SKILL.md +42 -0
  47. package/assets/skills/chaos/SKILL.md +41 -0
  48. package/assets/skills/cicd-pipeline/SKILL.md +56 -0
  49. package/assets/skills/cloud/SKILL.md +42 -0
  50. package/assets/skills/code-quality/SKILL.md +42 -0
  51. package/assets/skills/code-review/SKILL.md +41 -0
  52. package/assets/skills/communication/SKILL.md +42 -0
  53. package/assets/skills/containers/SKILL.md +42 -0
  54. package/assets/skills/cqrs/SKILL.md +41 -0
  55. package/assets/skills/crypto/SKILL.md +46 -0
  56. package/assets/skills/data-engineering/SKILL.md +42 -0
  57. package/assets/skills/database-design/SKILL.md +46 -0
  58. package/assets/skills/ddd/SKILL.md +45 -0
  59. package/assets/skills/deployment-strategies/SKILL.md +51 -0
  60. package/assets/skills/desktop/SKILL.md +42 -0
  61. package/assets/skills/devsecops/SKILL.md +43 -0
  62. package/assets/skills/event-driven/SKILL.md +46 -0
  63. package/assets/skills/frontend/SKILL.md +41 -0
  64. package/assets/skills/functional/SKILL.md +42 -0
  65. package/assets/skills/high-availability/SKILL.md +42 -0
  66. package/assets/skills/iac/SKILL.md +46 -0
  67. package/assets/skills/logging/SKILL.md +46 -0
  68. package/assets/skills/meta/ciel-improve/SKILL.md +127 -0
  69. package/assets/skills/meta/learnings-capture/SKILL.md +105 -0
  70. package/assets/skills/meta/patch-spec/patch-spec.md +50 -0
  71. package/assets/skills/meta/skill-creator/SKILL.md +115 -0
  72. package/assets/skills/meta/skill-freshness-auditor/SKILL.md +164 -0
  73. package/assets/skills/meta/skill-variant-evaluator/SKILL.md +100 -0
  74. package/assets/skills/meta/skills-first-design-auditor/SKILL.md +192 -0
  75. package/assets/skills/ml-engineering/SKILL.md +42 -0
  76. package/assets/skills/mobile/SKILL.md +42 -0
  77. package/assets/skills/monitoring/SKILL.md +54 -0
  78. package/assets/skills/networking/SKILL.md +42 -0
  79. package/assets/skills/nosql/SKILL.md +41 -0
  80. package/assets/skills/oop-solid/SKILL.md +42 -0
  81. package/assets/skills/performance/SKILL.md +41 -0
  82. package/assets/skills/reactive/SKILL.md +42 -0
  83. package/assets/skills/release-management/SKILL.md +51 -0
  84. package/assets/skills/research/fact-check-claims/SKILL.md +98 -0
  85. package/assets/skills/research/research-forums/SKILL.md +103 -0
  86. package/assets/skills/research/research-github-issues/SKILL.md +103 -0
  87. package/assets/skills/research/research-web-sources/SKILL.md +108 -0
  88. package/assets/skills/research/synthesize-findings/SKILL.md +112 -0
  89. package/assets/skills/research/validate-source-credibility/SKILL.md +103 -0
  90. package/assets/skills/resilience/SKILL.md +41 -0
  91. package/assets/skills/serverless/SKILL.md +42 -0
  92. package/assets/skills/servers/SKILL.md +41 -0
  93. package/assets/skills/sql/SKILL.md +45 -0
  94. package/assets/skills/supply-chain/SKILL.md +41 -0
  95. package/assets/skills/system-design/SKILL.md +91 -0
  96. package/assets/skills/tech-leadership/SKILL.md +46 -0
  97. package/assets/skills/testing/SKILL.md +41 -0
  98. package/assets/skills/tracing/SKILL.md +36 -0
  99. package/assets/skills/utility/branch-cleaner/SKILL.md +195 -0
  100. package/assets/skills/utility/branch-setup/SKILL.md +144 -0
  101. package/assets/skills/utility/changelog-updater/SKILL.md +125 -0
  102. package/assets/skills/utility/commit-writer/SKILL.md +154 -0
  103. package/assets/skills/utility/issue-closer/SKILL.md +106 -0
  104. package/assets/skills/utility/issue-creator/SKILL.md +200 -0
  105. package/assets/skills/utility/pr-merger/SKILL.md +189 -0
  106. package/assets/skills/utility/pr-opener/SKILL.md +180 -0
  107. package/assets/skills/utility/release-publisher/SKILL.md +224 -0
  108. package/assets/skills/workflow/ciel-dev-process/SKILL.md +94 -0
  109. package/assets/skills/workflow/faire-gatekeeper/SKILL.md +3 -1
  110. package/assets/skills/workflow/prouver-verifier/SKILL.md +11 -2
  111. package/dist/cli/check.d.ts.map +1 -1
  112. package/dist/cli/check.js +11 -2
  113. package/dist/cli/check.js.map +1 -1
  114. package/dist/cli/claude.d.ts.map +1 -1
  115. package/dist/cli/claude.js +0 -2
  116. package/dist/cli/claude.js.map +1 -1
  117. package/dist/cli/init.d.ts.map +1 -1
  118. package/dist/cli/init.js +11 -2
  119. package/dist/cli/init.js.map +1 -1
  120. package/dist/cli/opencode.d.ts.map +1 -1
  121. package/dist/cli/opencode.js +2 -1
  122. package/dist/cli/opencode.js.map +1 -1
  123. package/package.json +1 -1
  124. package/assets/commands/ciel-migrate.md +0 -35
  125. package/assets/commands/ciel-refresh.md +0 -91
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: skill-variant-evaluator
3
+ description: AutoResearch eval runner that generates 2-3 variants of a skill, executes them headlessly against binary eval datasets, compares aggregate scores, and proposes the winner with tiebreak on token usage. Use when /ciel-eval is invoked or when ciel-improve needs to pick between candidate rewrites.
4
+ allowed-tools: Read, Bash, Glob
5
+ ---
6
+
7
+ # skill-variant-evaluator — AutoResearch eval harness
8
+
9
+ ## What this covers
10
+ Implements Karpathy-style AutoResearch for Ciel skills: define binary evals, run variants, compare scores, keep the winner.
11
+
12
+ ## Core principle
13
+ **Binary evals, not vibes.** Every skill improvement is measured against concrete pass/fail criteria. The variant with the highest score wins.
14
+
15
+ ## Inputs
16
+
17
+ - **skill-path**: path to `SKILL.md`
18
+ - **variants** (optional): 2-3 candidate SKILL.md contents
19
+ - **dataset**: eval dataset in `evals/datasets/<name>.jsonl`
20
+ - **baseline-only**: boolean — only score current skill, no variants
21
+
22
+ ## Process
23
+
24
+ ### 1. Locate eval dataset
25
+
26
+ Look for `evals/datasets/<skill-name>.jsonl`. If missing, warn and exit.
27
+
28
+ ### 2. Load variants
29
+
30
+ - Variant A: current SKILL.md (baseline)
31
+ - Variants B, C: alternatives provided or from `variants/`
32
+
33
+ ### 3. Execute each variant headlessly
34
+
35
+ For each variant:
36
+ 1. Write to `SKILL.md.eval.<letter>`
37
+ 2. For each eval entry, run `claude --print` with the eval prompt
38
+ 3. Capture output + token usage + duration
39
+ 4. Score against `expected_behavior` criteria (binary per criterion)
40
+
41
+ ### 4. Aggregate scores
42
+
43
+ `aggregate = sum(criteria_passed) / total_criteria`
44
+
45
+ Winner = highest aggregate. Tiebreak: lowest total token usage.
46
+
47
+ ### 5. Persist results
48
+
49
+ Write to `evals/results/<skill-name>-<timestamp>.json`.
50
+
51
+ ## Common patterns
52
+
53
+ ### Good eval result
54
+
55
+ ```
56
+ # Skill variant evaluation — flux-narrator
57
+
58
+ Dataset: evals/datasets/flux-narration.jsonl (8 entries)
59
+
60
+ | Variant | Score | Tokens | Duration |
61
+ |---------|-------|--------|----------|
62
+ | A (baseline) | 0.72 | 14.5k | 12.5s |
63
+ | B (tightened) | 0.89 | 15.1k | 13.2s ← WINNER |
64
+ | C (reduced) | 0.81 | 12.8k | 11.7s |
65
+
66
+ Winner: **Variant B** (+0.17 over baseline)
67
+ Recommendation: adopt Variant B.
68
+ ```
69
+
70
+ ### Bad eval result
71
+
72
+ ```
73
+ Variant B seems better. Use it.
74
+ ```
75
+
76
+ Problems: no scores, no comparison table, no dataset reference.
77
+
78
+ ## Anti-patterns
79
+
80
+ - **Dataset > 20 entries** — cap to prevent runaway costs
81
+ - **> 3 variants** — no clear winner possible
82
+ - **Token cost > 500k without confirmation** — estimate first
83
+ - **Overwriting SKILL.md** — variants go to `.eval.<letter>` files
84
+ - **Not cleaning up** — delete `.eval.<letter>` temp files after results persisted
85
+
86
+ ## How to verify
87
+
88
+ - [ ] Dataset exists and loaded?
89
+ - [ ] All variants executed?
90
+ - [ ] Scores aggregated correctly?
91
+ - [ ] Winner identified with tiebreak if needed?
92
+ - [ ] Results persisted to `evals/results/`?
93
+ - [ ] Temp files cleaned up?
94
+ - [ ] Token cost within budget?
95
+
96
+ ## When triggered
97
+
98
+ - User runs `/ciel-eval [skill-name]`
99
+ - `ciel-improve` calls this for each proposed patch
100
+ - `improver` agent invokes this as part of its loop
@@ -0,0 +1,192 @@
1
+ ---
2
+ name: skills-first-design-auditor
3
+ description: Lints and audits Agent Skills (Anthropic format) for design quality — frontmatter completeness, body length ≤500 lines, presence of 2-3 concrete examples, verification scripts for critical checks, clear WHEN-triggered section, and alignment with the 6 principles from Anthropic's April 2026 skills guide. Used by @ciel-improver when creating or reviewing a skill.
4
+ allowed-tools: Read, Grep, Glob, Bash
5
+ context: fork
6
+ agent: improver
7
+ ---
8
+
9
+ # skills-first-design-auditor — Good skills discover themselves
10
+
11
+ A skill that doesn't auto-activate is just a document. Anthropic's April 2026 guide ("Equipping Agents for the Real World with Agent Skills") codifies what makes a skill actually useful to an agent. This skill audits against those principles.
12
+
13
+ ---
14
+
15
+ ## Inputs
16
+
17
+ ```
18
+ SKILL_PATH: [absolute path to a SKILL.md file OR a directory containing SKILL.md + companions]
19
+ ```
20
+
21
+ ---
22
+
23
+ ## The 6 principles (Anthropic April 2026)
24
+
25
+ ### 1. Evaluation-driven design
26
+
27
+ The skill must encode a capability the agent ACTUALLY lacks. Don't add skills that duplicate what the base model does well.
28
+
29
+ **Audit**: is there evidence (a failing eval, a user complaint, a prior incident) that motivated this skill? → Check git history / CHANGELOG entry.
30
+
31
+ ### 2. Searchable frontmatter
32
+
33
+ `description` must be specific enough that agents invoke it via semantic search. "Helps with code" is USELESS; "Validates that each proposed external API call exists in the pinned version's official documentation" is GOOD.
34
+
35
+ **Audit**:
36
+ - `name`: kebab-case, < 40 chars
37
+ - `description`: 1-3 sentences, names the trigger condition AND the output
38
+ - `allowed-tools`: present, minimal (`Read, Grep` not `*`)
39
+ - Agent field if applicable (`agent: critic` / `agent: researcher` / ...)
40
+
41
+ ### 3. Body ≤ 500 lines
42
+
43
+ Skills are loaded into agent context. A 2000-line skill burns 5k tokens just to be available. If the body exceeds 500 lines:
44
+
45
+ - Split into a core SKILL.md + reference docs in the same folder
46
+ - Link from SKILL.md to the references; agent fetches them on demand
47
+
48
+ **Audit**: `wc -l SKILL.md`. Frontmatter doesn't count. 500-700 lines = WARN. >700 = BLOCK.
49
+
50
+ ### 4. Concrete examples, not abstract prose
51
+
52
+ Each skill body must contain 2-3 examples showing input → reasoning → output. Not "the skill handles X" — an actual trace.
53
+
54
+ **Audit**: grep for `### Example` or `#### Example` or ```` ```<lang> `` code blocks with realistic values. 0 examples = BLOCK. 1 example = WARN. 2+ = PASS.
55
+
56
+ ### 5. Verification scripts for critical checks
57
+
58
+ If the skill includes a "is this condition met?" check, that check should be executable (bash, python, grep), not a prose instruction telling the agent to "verify visually". Executable checks are reliable; prose checks degrade.
59
+
60
+ **Audit**: does the PROCESS section contain at least one runnable command per check? If all checks are prose ("verify the input is valid") → WARN.
61
+
62
+ ### 6. Clear WHEN-triggered section
63
+
64
+ The skill must state explicitly when it activates: which step of the pipeline, which agent dispatches it, which user command. Without this, auto-activation via description-matching misfires.
65
+
66
+ **Audit**: presence of a `## When triggered` section (or equivalent) with at least 2 concrete triggers.
67
+
68
+ ---
69
+
70
+ ## Ciel-specific additions
71
+
72
+ ### A. Consistency with existing skills
73
+
74
+ - Same section order as peer skills in the same category (workflow/ research/ domain/ utility/ meta)
75
+ - Same frontmatter field ordering (`name`, `description`, `allowed-tools`, `context`, `agent`)
76
+ - Output format uses `##` + `###` hierarchy consistent with `relire-critic` style
77
+
78
+ ### B. No duplication
79
+
80
+ Before approving a new skill, grep the existing 36 skills for overlap. If the new skill covers ≥70% of an existing skill's scope → reject or merge.
81
+
82
+ ### C. Dispatch target aligned
83
+
84
+ `agent: <role>` must match where the skill logically fits:
85
+ - **researcher** — external investigation, doc fetching, source validation
86
+ - **explorer** — codebase reading, pattern detection, domain knowledge
87
+ - **critic** — post-write review, hostile analysis, correctness checking
88
+ - **improver** — meta-level, auditing other skills or the system itself
89
+
90
+ Wrong `agent:` = skill won't be dispatched via the right fork context.
91
+
92
+ ---
93
+
94
+ ## Audit output format
95
+
96
+ ```
97
+ ## SKILL AUDIT: <name>
98
+
99
+ ### Frontmatter
100
+ [✓] name: kebab-case, 22 chars
101
+ [✓] description: specific, names trigger + output
102
+ [✓] allowed-tools: minimal (Read, Grep, Glob, Bash)
103
+ [✓] agent: explorer (aligned with body content)
104
+
105
+ ### Body
106
+ [✓] Length: 342 lines (under 500)
107
+ [✓] Examples: 3 (passes minimum 2)
108
+ [✓] Executable checks: 4 (grep commands, wc -l, etc.)
109
+ [✓] "When triggered" section: present, 4 triggers listed
110
+
111
+ ### Principles
112
+ [✓] 1. Evaluation-driven — CHANGELOG v2.1.0 references ISSTA 2025 gap
113
+ [✓] 2. Searchable frontmatter
114
+ [✓] 3. Body ≤500 lines
115
+ [✓] 4. Concrete examples
116
+ [✓] 5. Verification scripts
117
+ [✓] 6. WHEN-triggered clarity
118
+
119
+ ### Ciel-specific
120
+ [✓] Consistent section order with peer skills in workflow/
121
+ [✓] No overlap with existing skills (checked: pattern-fitness-check, flux-narrator)
122
+ [✓] agent field matches skill content (explorer for codebase-reading)
123
+
124
+ ### Findings
125
+ (none — skill passes audit)
126
+
127
+ ### Verdict
128
+ PASS — ready to ship
129
+ ```
130
+
131
+ ---
132
+
133
+ ## Typical issues found (with fixes)
134
+
135
+ ### Issue: vague description
136
+ ```yaml
137
+ # BAD
138
+ description: Helps with code review.
139
+ # GOOD
140
+ description: Generates 3 hostile critiques per changed file (1 functional, 1 import, 1 data-assumption) and resolves each with FIX/ACCEPT/DEFER. Invoked by the PostToolUse hook on Write/Edit for Standard/Critical tasks with 3+ changed files.
141
+ ```
142
+
143
+ ### Issue: no examples
144
+ Add at least 2 concrete `### Example` blocks showing input → skill output. Prose-only skills don't transfer knowledge well; examples anchor behavior.
145
+
146
+ ### Issue: missing WHEN section
147
+ Add section listing: (a) pipeline step, (b) dispatching agent, (c) user command triggers. 4-6 bullets is plenty.
148
+
149
+ ### Issue: overbroad allowed-tools
150
+ ```yaml
151
+ # BAD
152
+ allowed-tools: "*"
153
+ # GOOD
154
+ allowed-tools: Read, Grep, Glob, Bash
155
+ ```
156
+
157
+ ---
158
+
159
+ ## How to verify
160
+
161
+ - [ ] All 6 Anthropic principles checked?
162
+ - [ ] Frontmatter audit complete (name, description, allowed-tools, agent)?
163
+ - [ ] Body length measured (wc -l)?
164
+ - [ ] Examples counted (grep for Example blocks)?
165
+ - [ ] Verification scripts checked (executable vs prose)?
166
+ - [ ] WHEN-triggered section present?
167
+ - [ ] Ciel-specific checks (consistency, no duplication, dispatch target)?
168
+
169
+ ## Guardrails
170
+
171
+ - **Don't auto-fix, just audit** — propose changes in the report; let the human/improver decide.
172
+ - **Don't re-audit on every commit** — this is a "when a skill is added or significantly edited" task.
173
+ - **Prior-session skills** count under principle 1 — if the skill came from a past Ciel iteration and was never re-validated, flag for re-evaluation.
174
+ - **Skills in `skills/meta/`** should be extra strict — they shape how the system grows.
175
+ - **Exceptions allowed** — a meta skill legitimately exceeds 500 lines if it encodes a taxonomy; document the rationale in a comment at the top of the file.
176
+
177
+ ---
178
+
179
+ ## When triggered
180
+
181
+ - `@ciel-improver` on `/ciel-create-skill`
182
+ - PR touching `skills/**/SKILL.md`
183
+ - Before merging a skill from a research branch
184
+ - Quarterly sweep across all skills (release gate)
185
+
186
+ ---
187
+
188
+ ## References
189
+
190
+ - Anthropic April 2026 — "Equipping Agents for the Real World with Agent Skills" — anthropic.com/engineering
191
+ - Anthropic Skills intro — anthropic.skilljar.com/introduction-to-agent-skills
192
+ - Claude API docs — platform.claude.com/docs/en/agents-and-tools/agent-skills/overview
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: ml-engineering
3
+ description: "ML Engineering — pipelines ML, feature stores, model serving, drift detection, MLOps, experiment tracking. A charger quand on met en production des modeles ML."
4
+ ---
5
+
6
+ # ML Engineering
7
+
8
+ **Principe premier :** Le ML engineering n'est pas "entrainer un modele avec le meilleur score" — c'est mettre un modele en production et garantir qu'il reste performant dans le temps. La metrique qui compte n'est pas l'accuracy sur le dataset de test (qui est un instantane du passe) — c'est la performance en production sur les donnees de demain. Un modele est un programme qui se degrade passivement : le monde change, les distributions derivent, et un modele a 98% de precision aujourd'hui peut tomber a 72% dans 6 mois sans que personne ne le sache. La difference entre un notebook Jupyter et un systeme ML de production, c'est le monitoring, le versioning, et la capacite a re-entrainer.
9
+
10
+ ## Checklist
11
+ - [ ] Les donnees sont versionnees (DVC, LakeFS, Delta Lake) — pas de `dataset_v3_final_FINAL.csv`
12
+ - [ ] Les experiences sont trackees (MLflow, W&B, ClearML) avec hyperparametres, code version, dataset version
13
+ - [ ] Le feature store est la source unique de verite pour les features — pas de features calculees differemment en train et en inference
14
+ - [ ] Le serving est monitorise : latence P95, taux d'erreur, distribution des predictions
15
+ - [ ] Le data drift ET le concept drift sont monitorises — alerter quand la distribution change
16
+ - [ ] Le pipeline d'entrainement est reproductible (DAG, conteneurise, versionne)
17
+ - [ ] Le rollback de modele est aussi simple que le rollback de code (model registry avec versioning)
18
+
19
+ ## Anti-patterns
20
+ ### Notebook → production
21
+ **Ce qu'on voit :** le data scientist donne son notebook "il marche sur mon laptop". L'ingenieur le copie-colle dans un endpoint. 2000 lignes de code non structure.
22
+ **Pourquoi c'est dangereux :** un notebook n'est pas un programme — c'est un journal d'exploration. Pas de gestion d'erreur, pas de typage, pas de tests, pas de reproductibilite (execution ordonnee non garantie). Les imports sont eparpilles, les variables persistent entre cellules, le code est impossible a maintenir.
23
+ **Faire plutot :** le notebook est un outil d'exploration. Le code de production est dans des modules Python standards, versionnes, testes. Le data scientist et le ML engineer travaillent ensemble sur la transition notebook → module. Le notebook documente l'intention, le module implemente la production.
24
+
25
+ ### Features train/serve inconsistantes
26
+ **Ce qu'on voit :** les features sont calculees en Python (pandas) pour l'entrainement, et en Go/Java dans le serving. Implementation differente → comportement different → modele qui performe mal en production sans raison apparente.
27
+ **Pourquoi c'est dangereux :** c'est le bug le plus pernicieux en ML. Les metriques d'entrainement sont bonnes, les tests passent, mais le modele est mauvais en production. La cause est quasi impossible a debugger sans comparer les implementations feature par feature.
28
+ **Faire plutot :** feature store central. Les memes features, calculees par le meme code, servent l'entrainement ET l'inference. Si le calcul change, le feature store versionne. Zero implementation divergente.
29
+
30
+ ### Drift = surprise
31
+ **Ce qu'on voit :** pas de monitoring du drift. Le modele se degrade lentement. 6 mois plus tard, un utilisateur remarque que les predictions sont mauvaises.
32
+ **Pourquoi c'est dangereux :** la degradation est silencieuse et graduelle. Le modele ne crash pas — il devient juste de plus en plus mauvais. Les decisions basees sur ces predictions deviennent de plus en plus mauvaises. Le MTTD (mean time to detect) est de 6 mois.
33
+ **Faire plutot :** monitoring continu de la distribution des features en production vs distribution d'entrainement (data drift). Monitoring des predictions (concept drift : relation feature → cible qui change). Alerter quand la divergence depasse un seuil. Re-entrainement automatise ou manuel selon la criticite.
34
+
35
+ ## Patterns
36
+ ### Model registry
37
+ **Quand :** plusieurs modeles en production ou re-entrainements frequents.
38
+ **Comment :** MLflow Model Registry, Seldon, ou Sagemaker Model Registry. Chaque modele a : version, metriques, dataset d'origine, artefact, statut (staging/production/archived). Promotion staging → production via CI/CD. Rollback = pointer vers la version precedente en un clic.
39
+
40
+ ### Feature store
41
+ **Quand :** features reutilisees entre plusieurs modeles ou entre train/serving.
42
+ **Comment :** Feast, Tecton, ou solution interne. Les features sont definies une fois, calculees offline (batch) et servies online (low latency). Le feature store garantit la consistance entre train et serve. Chaque feature est versionnee et documentee.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: mobile
3
+ description: "Mobile — iOS/Android/React Native/Flutter, offline-first, batterie, store review, push notifications. A charger quand on developpe une application mobile."
4
+ ---
5
+
6
+ # Mobile
7
+
8
+ **Principe premier :** Le mobile n'est pas "un petit ecran" — c'est un environnement hostile. Reseau instable (tunnel → metro → edge → 3G), batterie limitee, stockage restreint, OS qui peut killer l'app a tout moment. Si ton app ne fonctionne pas dans un tunnel avec 1 barre de 3G et 10% de batterie, elle ne fonctionne pas. Le store (App Store, Play Store) est ton canal de distribution mais aussi ton gatekeeper — chaque release est une revue humaine qui peut etre rejetee. Le mobile recompense l'optimisme offline et le pessimisme reseau : suppose toujours que le reseau est lent, cher, et hostile.
9
+
10
+ ## Checklist
11
+ - [ ] Offline-first : l'app fonctionne sans reseau — donnees en cache local, actions en file d'attente
12
+ - [ ] Les images sont lazy-loadees et resizees (pas de 4K telecharge sur un ecran 400px de large)
13
+ - [ ] La batterie est respectee : pas de polling every 5s, pas de wake lock permanent, pas de GPS continu
14
+ - [ ] Le state est preserve a travers les kills d'OS (serialisation automatique du state critique)
15
+ - [ ] Les crashs sont reportes (Crashlytics, Sentry) — pas de "ca crash sur le telephone de Julie"
16
+ - [ ] Les updates sont gerees : forced update si API incompatible, optional update sinon
17
+ - [ ] Le stockage local a un TTL et une limite de taille — pas de cache infini qui remplit le telephone
18
+
19
+ ## Anti-patterns
20
+ ### Mobile = site web en webview
21
+ **Ce qu'on voit :** une webview qui charge le site responsive. Publie sur les stores. "Ca marche sur mobile."
22
+ **Pourquoi c'est dangereux :** zero integration native. Pas de push notifications, pas de stockage offline, pas de gestures natives, pas de transition fluide. Les utilisateurs le sentent immediatement et desinstallent. Les stores peuvent rejeter si l'app n'apporte rien par rapport au site.
23
+ **Faire plutot :** si le contenu est statique → PWA (plus leger, pas besoin de store). Si besoin natif (push, camera, offline) → app native ou React Native/Flutter avec vrais composants natifs.
24
+
25
+ ### Optimiste sur le reseau
26
+ **Ce qu'on voit :** l'app suppose que le reseau est disponible et rapide. Pas de cache, pas de queue offline, pas de gestion d'erreur reseau. L'app affiche un spinner blanc des que le reseau est lent.
27
+ **Pourquoi c'est dangereux :** le reseau mobile est le pire reseau de tous les clients. L'utilisateur est dans un ascenseur, un metro, une cave, une campagne. Si l'app ne fonctionne pas offline, elle est inutilisable 30% du temps. L'utilisateur ouvre l'app concurrente.
28
+ **Faire plutot :** cache local (SQLite, Realm, WatermelonDB). Sync en arriere-plan quand le reseau est disponible. UI qui montre les donnees en cache immediatement, puis rafraichit. Indicateur "donnees de X minutes" plutot qu'un spinner.
29
+
30
+ ### Release = pari
31
+ **Ce qu'on voit :** soumission sur le store sans test de recette. Rejet pour violation de guideline. 3 jours de delai. Corrections en catastrophe.
32
+ **Pourquoi c'est dangereux :** le store review est un processus humain, lent, et imprevisible. Un rejet decale la release de 3-7 jours. Les utilisateurs attendent, les bugs critiques restent en production.
33
+ **Faire plutot :** pre-release checklist (guidelines store, screenshots, permissions documentees). TestFlight/Internal Testing pour valider le binaire avant soumission. Soumission en debut de semaine pour maximiser les chances de review rapide.
34
+
35
+ ## Patterns
36
+ ### Offline-first avec sync queue
37
+ **Quand :** app qui modifie des donnees (notes, taches, commandes).
38
+ **Comment :** ecriture locale immediate → queue de synchronisation → synchro background quand online. Resolution de conflits : last-write-wins pour donnees simples, merge pour donnees complexes. UI qui montre l'etat de synchro (sync, synced, error).
39
+
40
+ ### Gradual rollout sur stores
41
+ **Quand :** release avec risque (refonte, nouvelle fonctionnalite).
42
+ **Comment :** Play Store : staged rollout (10% → 50% → 100% avec possibilite de halt). App Store : phased release sur 7 jours. Monitoring des crashs et des ratings par version. Rollback en arretant le rollout (pas besoin de nouvelle soumission).
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: monitoring
3
+ description: "Monitoring — RED/USE metrics, SLI/SLO/SLA comme contrats, dashboards comme outils de debugging, alerting fatigue. À charger quand on met en place du monitoring."
4
+ ---
5
+
6
+ # Monitoring
7
+
8
+ **Principe premier :** Le monitoring n'est pas "avoir des dashboards" — c'est pouvoir répondre à deux questions en < 30 secondes : "est-ce que le système fonctionne ?" et "si non, qu'est-ce qui a changé ?". Si tes dashboards ne répondent pas à ça, ils sont du bruit visuel. La métrique fondamentale n'est pas le nombre de graphiques — c'est le Mean Time To Detect (MTTD). Combien de temps entre le début de l'incident et la première alerte ? Si la réponse est "quand un client ouvre un ticket", ton monitoring a échoué.
9
+
10
+ ## Checklist
11
+ - [ ] RED metrics par service : Rate, Errors, Duration (P50/P95/P99) — collectées via Prometheus, exposées sur `/metrics`
12
+ - [ ] USE metrics par ressource : Utilization, Saturation, Errors — node_exporter/cAdvisor → Prometheus → Grafana
13
+ - [ ] Dashboards, règles Prometheus, et config AlertManager sont dans le repo (monitoring as code) — pas créés à la main dans l'UI Grafana
14
+ - [ ] Dashboards Grafana avec seuils visuels (vert/jaune/rouge) — pas juste des lignes sur un graphique
15
+ - [ ] SLI définis (ce qu'on mesure), SLO documentés (l'objectif), SLA communiqués (la promesse)
16
+ - [ ] Alertes sur les signaux critiques uniquement — pas d'alerte sur "CPU > 70% pendant 30s à 3h du matin"
17
+ - [ ] Runbook associé à chaque alerte — "si cette alerte sonne, voici quoi faire"
18
+
19
+ ## Anti-patterns
20
+ ### Dashboard = décoration
21
+ **Ce qu'on voit :** un écran mural avec 50 graphiques, pas de titre, pas d'échelle, pas de seuil. Personne ne le regarde. Les incidents sont découverts par les utilisateurs.
22
+ **Pourquoi c'est dangereux :** un dashboard sans contexte n'est pas un outil — c'est du bruit. Les anomalies sont noyées dans la masse de données non interprétables. Le MTTD est infini.
23
+ **Faire plutôt :** un dashboard par service. Titre explicite. Description : "Ce dashboard montre la santé du service X. Si ce graphique est rouge, regarder Y." Seuils visuels. Maximum 10 métriques par dashboard. Le dashboard doit permettre de répondre "est-ce que c'est normal ?" en un coup d'œil.
24
+
25
+ ### Alerte sur tout
26
+ **Ce qu'on voit :** 200 alertes configurées. "CPU > 50%", "mémoire > 60%", "disque > 70%". 15 alertes par nuit. L'équipe a muté le canal. Les vraies urgences sont ignorées.
27
+ **Pourquoi c'est dangereux :** l'alert fatigue est réelle. Chaque fausse alerte entraîne la suivante vers l'ignorance. Quand une vraie alerte critique arrive, personne ne la voit parce que tout le monde a appris que "les alertes = du bruit".
28
+ **Faire plutôt :** alerter sur les SYMPTÔMES, pas sur les causes potentielles. "P95 latency > 1s pendant 5 min" (symptôme utilisateur), pas "CPU > 70%" (cause possible). Chaque alerte doit être actionable — si tu ne peux pas écrire le runbook en 3 étapes, ne crée pas l'alerte.
29
+
30
+ ### Monitoring = dashboards Grafana
31
+ **Ce qu'on voit :** tout est dans Grafana. Pas de logs structurés, pas de tracing, pas d'alerting. "On regardera le dashboard si quelqu'un se plaint."
32
+ **Pourquoi c'est dangereux :** le monitoring sans observabilité, c'est regarder le tableau de bord de ta voiture. Tu vois que la vitesse est à 0, mais tu ne sais pas POURQUOI. Les dashboards montrent les symptômes, les logs et traces montrent les causes. L'un sans l'autre = tu sais que c'est cassé, pas pourquoi.
33
+ **Faire plutôt :** monitoring (métriques + dashboards + alertes) + logging (logs structurés JSON + correlation ID) + tracing (OpenTelemetry, traces distribuées). Les trois piliers de l'observabilité.
34
+
35
+ ## Patterns
36
+ ### Prometheus + Grafana (stack standard)
37
+ **Quand :** toute application en production.
38
+ **Comment :** Prometheus scrape les métriques exposées par l'app (`/metrics`). Grafana interroge Prometheus (PromQL) et affiche les dashboards. Pas de solution propriétaire — cette stack est le standard ouvert, toutes les bibliothèques l'implémentent. Chaque service expose ses propres métriques RED, l'infrastructure expose les USE via node_exporter / cAdvisor.
39
+
40
+ ### RED method (services)
41
+ **Quand :** monitoring de tout service (API, worker, etc.).
42
+ **Comment :** Rate (requêtes/s), Errors (taux d'erreur), Duration (P50/P95/P99) via histogram Prometheus. 3 métriques par endpoint. Couvre l'expérience utilisateur. PromQL : `rate(http_requests_total[5m])`, `rate(http_errors_total[5m])`, `histogram_quantile(0.95, rate(http_duration_bucket[5m]))`.
43
+
44
+ ### USE method (ressources)
45
+ **Quand :** monitoring de toute ressource (CPU, RAM, disque, réseau, DB pool).
46
+ **Comment :** Utilization (% utilisé), Saturation (file d'attente), Errors (compteur d'erreurs) via node_exporter. 3 métriques par ressource. Dashboard Grafana avec seuils vert/jaune/rouge. Si Utilization > 80%, si Saturation > 0, si Errors > 0 — investiguer.
47
+
48
+ ### SLO-based alerting
49
+ **Quand :** définir les alertes sans tomber dans l'alert fatigue.
50
+ **Comment :** définir un SLO (ex: "99.9% des requêtes < 500ms sur 30 jours"). L'alerte se déclenche quand le error budget est consommé trop vite (ex: 5% du budget mensuel en 1h). Configurer dans AlertManager via Prometheus rules : `alert: HighErrorBurnRate`, `expr: rate(http_errors_total[1h]) / rate(http_requests_total[1h]) > 0.05`.
51
+
52
+ ### Monitoring as Code (dashboards + rules dans le repo)
53
+ **Quand :** toute équipe de plus d'une personne.
54
+ **Comment :** dashboards Grafana en JSON (Grafonnet pour les générer), règles Prometheus en YAML, config AlertManager en YAML — tout dans `monitoring/` du repo. Déploiement via CI/CD (Terraform, Grafana provisioning API). PR pour chaque changement de dashboard ou alerte. Le monitoring est de l'infrastructure — le même niveau de rigueur que le Terraform de prod.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: networking
3
+ description: "Networking — le reseau comme fondation invisible. DNS, TLS, HTTP/2/3, VPC, firewall, load balancing. A charger quand on configure des connexions ou debug la connectivite."
4
+ ---
5
+
6
+ # Networking
7
+
8
+ **Principe premier :** Le reseau n'est pas "ce qui connecte les machines" — c'est la couche de securite zero. Avant que ton application ne recoive un octet, le reseau a deja pris 100 decisions : routage, filtrage, terminaison TLS, rate limiting. Un reseau bien configure rend 80% des attaques impossibles avant meme qu'elles n'atteignent l'application. Le probleme inverse : un reseau mal configure est invisible jusqu'a l'incident — "pourquoi le service B ne peut pas parler au service C en prod ?" La connectivite n'est jamais acquise — elle est configuree, testee, monitorisee.
9
+
10
+ ## Checklist
11
+ - [ ] DNS est configure avec TTL raisonnable (300s pour APEX, 60s pour failover) — pas de TTL de 86400s
12
+ - [ ] TLS >= 1.2 partout, TLS 1.3 pour les services internes — pas de TLS 1.0/1.1, pas de SSL
13
+ - [ ] Les certificats sont auto-renouveles (LetsEncrypt, cert-manager, ACM) — pas d'expiration surprise
14
+ - [ ] Firewall : seuls les ports necessaires sont ouverts. SSH (22) restreint par IP source
15
+ - [ ] Les VPC/VNET sont isoles par environnement (dev/staging/prod) avec peering explicite
16
+ - [ ] HTTP/2 ou HTTP/3 active — multiplexing, header compression, 0-RTT
17
+ - [ ] Le load balancer a un health check actif (pas juste TCP connect — verifier le endpoint)
18
+
19
+ ## Anti-patterns
20
+ ### "C'est un probleme reseau"
21
+ **Ce qu'on voit :** chaque bug de connexion est blame sur "le reseau". Personne ne debug. Le probleme persiste 3 semaines.
22
+ **Pourquoi c'est dangereux :** le reseau est un bouc emissaire facile parce qu'il est invisible. En realite, la plupart des problemes "reseau" sont des problemes d'application : timeout trop court, DNS cache, certificat expire, mauvais endpoint. Dire "c'est le reseau" sans preuve = arreter de chercher.
23
+ **Faire plutot :** debug methodique : `dig` (DNS), `curl -v` (TLS + HTTP), `traceroute` (routage), `telnet host port` (connectivite brute). Chaque couche se teste independamment. Le probleme est toujours sur UNE couche specifique.
24
+
25
+ ### Firewall = apres coup
26
+ **Ce qu'on voit :** le firewall est configure "quand tout marche" (jamais). Tous les ports sont ouverts "pour pas etre bloque".
27
+ **Pourquoi c'est dangereux :** le firewall est la premiere ligne de defense. Sans regles strictes, une application vulnerable sur un port oublie = acces non autorise. Le firewall interne (entre services) est aussi important que l'externe.
28
+ **Faire plutot :** deny-all par defaut. Ouvrir uniquement les flux documentes. Chaque regle a un commentaire (pourquoi ce port, pour quel service). Revue trimestrielle des regles.
29
+
30
+ ### DNS comme apres-pensee
31
+ **Ce qu'on voit :** TTL = 86400 (24h). Changement de serveur → 24h de propagation. Les utilisateurs voient l'ancienne IP. Ou pire : `CNAME` court-circuite avec un `A` record parce que "c'est plus simple".
32
+ **Pourquoi c'est dangereux :** DNS est le premier maillon de toute connexion. Un TTL trop long empeche le failover rapide. Un mauvais enregistrement = outage total. Le DNS est la fondation — tout repose dessus.
33
+ **Faire plutot :** TTL courts pour les endpoints critiques (60-300s). Records A/AAAA pour la racine, CNAME pour les sous-domaines. Monitoring de resolution DNS depuis plusieurs points geographiques.
34
+
35
+ ## Patterns
36
+ ### Defense en profondeur reseau
37
+ **Quand :** architecture multi-services.
38
+ **Comment :** WAF/CDN (couche 1) → Load Balancer + TLS termination (couche 2) → Network ACL/VPC firewall (couche 3) → Security Group par service (couche 4). Chaque couche suppose que la precedente a echoue. Aucune couche ne fait confiance a la precedente.
39
+
40
+ ### Zero Trust networking
41
+ **Quand :** services distribues, multi-cloud, ou travailleurs distants.
42
+ **Comment :** pas de "reseau interne de confiance". Chaque appel est authentifie (mTLS, JWT, SPIFFE). Le reseau est hostile par defaut — les services ne se font pas plus confiance entre eux qu'a Internet. C'est le principe inverse du "perimetre de securite".
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: nosql
3
+ description: "NoSQL — MongoDB/DynamoDB/Redis, modeling around access patterns, single-table design, hot partition avoidance. À charger quand on choisit ou utilise du NoSQL."
4
+ ---
5
+
6
+ # NoSQL
7
+
8
+ **Principe premier :** NoSQL n'est pas "SQL sans schéma" — c'est un trade-off fondamental : tu échanges la flexibilité des requêtes (tu ne peux pas tout JOINer) contre la scalabilité horizontale (tu peux sharder). Ce trade-off est le SEUL critère valide pour choisir NoSQL. Si tu n'as pas de problème de scale horizontal que SQL ne résout pas, NoSQL est un downgrade, pas une modernisation. Le modeling NoSQL se fait à l'envers du relationnel : tu pars des requêtes (qu'est-ce que je dois lire en une opération ?) et tu construis le modèle autour.
9
+
10
+ ## Checklist
11
+ - [ ] Le choix NoSQL est justifié par le scale horizontal, pas par "c'est plus simple"
12
+ - [ ] Le modèle de données est conçu autour des access patterns (et pas l'inverse)
13
+ - [ ] La partition key a une haute cardinalité et une distribution uniforme
14
+ - [ ] Les index secondaires (GSI) sont justifiés — chaque GSI coûte de l'argent et de la latence
15
+ - [ ] La stratégie de dénormalisation est documentée : quelle donnée est dupliquée, où, pourquoi
16
+ - [ ] Les TTL sont configurés pour les données temporaires — pas de job de nettoyage manuel
17
+
18
+ ## Anti-patterns
19
+ ### Modélisation relationnelle dans NoSQL
20
+ **Ce qu'on voit :** 12 `$lookup` (MongoDB) pour reproduire un JOIN. 50 `GetItem` séquentiels (DynamoDB) parce que les données sont dans des items séparés.
21
+ **Pourquoi c'est dangereux :** NoSQL n'est pas optimisé pour les JOINs. Chaque `$lookup` est un scan coûteux. Chaque `GetItem` est une requête réseau. 50 requêtes séquentielles DynamoDB = 500ms de latence minimum contre 10ms pour un JOIN SQL. Tu paies le prix du NoSQL sans le bénéfice.
22
+ **Faire plutôt :** pre-joindre. Si les données sont lues ensemble, elles sont stockées ensemble (single document/item). Le modèle reflète les patterns d'accès — une requête = un read.
23
+
24
+ ### Hot partition / hot key
25
+ **Ce qu'on voit :** partition key = `status` avec 90% des items à `status = "active"`. Ou pire, partition key = `tenant_id` et un tenant fait 80% du trafic.
26
+ **Pourquoi c'est dangereux :** en NoSQL, les partitions sont l'unité de scale. Une partition chaude = tout le trafic sur un seul shard = throttling (DynamoDB) ou performance dégradée (MongoDB). Le scale horizontal est neutralisé par une mauvaise clé.
27
+ **Faire plutôt :** partition key à haute cardinalité et distribution uniforme. `user_id`, `order_id`, pas de `status` ou `type`. Si un tenant est plus gros, sharder par `tenant_id#entity_id` (composite key).
28
+
29
+ ### Redis comme source de vérité
30
+ **Ce qu'on voit :** toutes les données métier dans Redis. `FLUSHALL` ou reboot = toutes les données perdues. "Mais j'ai configuré la persistence" — qui n'a jamais été testée.
31
+ **Pourquoi c'est dangereux :** Redis est conçu comme un cache/queue/session store en mémoire. La persistence Redis (RDB/AOF) est asynchrone et non garantie. Même avec AOF everysec, tu peux perdre les 2 dernières secondes d'écritures.
32
+ **Faire plutôt :** PostgreSQL/MySQL/DynamoDB pour la source de vérité. Redis pour cache, sessions, rate limiting, queues temporaires. Si Redis est flush, l'app dégrade mais ne perd pas de données métier.
33
+
34
+ ## Patterns
35
+ ### Single-table design (DynamoDB)
36
+ **Quand :** plusieurs types d'entités avec des access patterns différents.
37
+ **Comment :** une table. PK = `TYPE#id`, SK = `RELATION#id`. Les GSI inversent PK/SK pour les autres patterns. Un user et ses orders sont dans la même table, lus en une query. Pas de JOIN.
38
+
39
+ ### TTL index
40
+ **Quand :** données temporaires (sessions, cache, logs éphémères).
41
+ **Comment :** champ `expires_at` en epoch seconds + TTL index. La DB supprime automatiquement. Pas de cron job. Pas de nettoyage manuel. Gratuit (DynamoDB) ou quasi-gratuit.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: oop-solid
3
+ description: "OOP & SOLID — classes, objets, heritage, composition, encapsulation, principes SOLID comme garde-fous. A charger quand on travaille avec des classes."
4
+ ---
5
+
6
+ # OOP & SOLID
7
+
8
+ **Principe premier :** SOLID n'est pas un dogme — c'est un systeme d'alerte precoce. Chaque principe ne te dit pas quoi faire, il te dit QUAND le design est en train de pourrir. Single Responsibility = ta classe a plus d'une raison de changer. Open/Closed = tu modifies du code existant au lieu d'etendre. Liskov = ta sous-classe ne peut pas remplacer la classe mere. Interface Segregation = tes clients dependent d'interfaces qu'ils n'utilisent pas. Dependency Inversion = tes modules de haut niveau dependent des bas niveau. Le but n'est pas un score SOLID parfait — c'est un code qui accepte le changement sans se briser. La composition est par defaut, l'heritage est l'exception.
9
+
10
+ ## Checklist
11
+ - [ ] Chaque classe a une responsabilite unique (SRP) — decrire son job en une phrase sans "et"
12
+ - [ ] Les classes sont ouvertes a l'extension, fermees a la modification (OCP) — nouveau comportement = nouveau code, pas modification
13
+ - [ ] Les sous-classes sont substituables a leur classe mere (LSP) — pas de `if (obj instanceof SpecialCase)`
14
+ - [ ] Les interfaces sont minimales (ISP) — pas d'interface de 15 methodes dont 10 jettent `NotImplementedException`
15
+ - [ ] Les modules haut niveau ne dependent pas des bas niveau (DIP) — les deux dependent d'abstractions
16
+ - [ ] L'heritage est utilise pour "est-un", pas pour reutiliser du code — composition > heritage
17
+ - [ ] Le couplage est reduit : un changement dans une classe ne force pas une cascade de changements
18
+
19
+ ## Anti-patterns
20
+ ### SOLID comme religion
21
+ **Ce qu'on voit :** chaque classe est precedee de `interface IFoo`. Chaque `new` est remplace par une factory + DI container. 50 classes pour afficher "Hello World".
22
+ **Pourquoi c'est dangereux :** SOLID utilise en dogme produit l'inverse de son intention : code rigide, difficile a changer, difficile a comprendre. Une interface pour chaque classe = explosion du nombre de fichiers. DI partout = perdu dans les couches d'indirection.
23
+ **Faire plutot :** appliquer SOLID la ou le changement est PROBABLE. Un composant stable peut violer SOLID — c'est acceptable. Introduire une abstraction quand un deuxieme cas concret apparait (pas avant). SOLID est un outil de diagnostic, pas un objectif de design.
24
+
25
+ ### Heritage deep chain
26
+ **Ce qu'on voit :** `Animal → Mammal → Canine → Dog → Labrador → GoldenLabrador`. Chaque classe ajoute un comportement. Pour comprendre `GoldenLabrador`, il faut lire 6 classes.
27
+ **Pourquoi c'est dangereux :** l'heritage profond cree un couplage vertical. Changer `Animal` affecte toutes les 200 sous-classes. Impossible de comprendre une classe isolement. Le YAGNI frappe fort : la plupart des classes intermediaires ne sont jamais utilisees directement.
28
+ **Faire plutot :** limiter a 1-2 niveaux d'heritage maximum. Composer les comportements (Strategy, Decorator) plutot qu'heriter. Si une classe a plus de 2 ancetres concrets, repenser le design.
29
+
30
+ ### Classe "Manager" / "Utils" / "Helper"
31
+ **Ce qu'on voit :** `UserManager` (3000 lignes), `DateUtils` (150 fonctions statiques), `StringHelper` (tout le monde ajoute des trucs).
32
+ **Pourquoi c'est dangereux :** les noms en -Manager, -Utils, -Helper sont des aveux d'echec de design. Ils ne disent rien sur ce que fait la classe. Ils attirent le code non relie comme un aimant. Une classe qui s'appelle `Manager` n'a pas de responsabilite — elle en a 50.
33
+ **Faire plutot :** nommer les classes par leur responsabilite reelle. `UserRepository`, `UserAuthenticator`, `UserNotificationSender`. Si une classe a plus de 10 methodes publiques, la splitter par responsabilite. Les "utils" sont un signe qu'un concept manque dans le domaine.
34
+
35
+ ## Patterns
36
+ ### Composition over inheritance
37
+ **Quand :** quasi tout le temps.
38
+ **Comment :** au lieu de `class Duck extends Bird extends Animal`, injecter les comportements : `class Duck { constructor(flyBehavior, quackBehavior, swimBehavior) }`. Chaque comportement est interchangeable. Testable independamment. Le duck peut changer de FlyBehavior au runtime.
39
+
40
+ ### Dependency injection par constructeur
41
+ **Quand :** toute classe qui depend d'un service externe (DB, API, file system).
42
+ **Comment :** `constructor(db: Database, logger: Logger)` — les dependances sont explicites. Pas de `new Database()` dans la classe. Pas de singleton global (`Database.getInstance()`). Le test peut injecter un mock/adaptateur. La classe ne sait pas CREER ses dependances, elle les RECOIT.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: performance
3
+ description: "Performance — mesurer avant d'optimiser, P95 > moyenne, performance budgets, profiling, N+1, slow queries. À charger quand on parle d'optimisation."
4
+ ---
5
+
6
+ # Performance
7
+
8
+ **Principe premier :** "Make it work, make it right, make it fast" — dans cet ordre. La performance est une feature, pas une propriété magique. Comme toute feature, elle a un coût et doit être mesurée. Le piège classique est l'optimisation prématurée : du code complexe et illisible pour gagner 5ms sur un endpoint appelé 10×/jour. La règle d'or : ne jamais optimiser sans avoir mesuré. Le bottleneck réel n'est presque jamais là où on pense. Et la métrique qui compte n'est pas la moyenne — c'est le P95 (ou P99). La moyenne ment parce qu'elle cache les outliers, et ce sont les outliers qui pourrissent l'expérience utilisateur.
9
+
10
+ ## Checklist
11
+ - [ ] Profiling AVANT optimisation — jamais d'optimisation sur une intuition
12
+ - [ ] Métriques RED par endpoint : Rate, Errors, Duration (P50, P95, P99)
13
+ - [ ] Les requêtes N+1 sont identifiées et résolues (eager loading, batch, JOIN)
14
+ - [ ] Performance budget dans la CI : JS < 200KB, LCP < 2.5s, P95 < 500ms
15
+ - [ ] Les requêtes lentes sont loguées (> 100ms) avec EXPLAIN automatique
16
+ - [ ] Cache en place avec TTL explicite — pas de calcul redondant sur la hot path
17
+
18
+ ## Anti-patterns
19
+ ### Optimisation prématurée
20
+ **Ce qu'on voit :** micro-optimisations de boucles, bit-shifting, allocation pooling — sur un endpoint appelé 100×/jour. Le code est devenu illisible pour gagner 2ms.
21
+ **Pourquoi c'est dangereux :** l'optimisation prématurée a un double coût : le code devient plus dur à maintenir, et le temps passé à optimiser n'est pas passé sur des vrais problèmes. Pire : l'optimisation cible souvent le mauvais endroit parce qu'elle est basée sur l'intuition, pas sur la mesure.
22
+ **Faire plutôt :** "Make it work, make it right, make it fast." Mesurer. Profiler. Identifier le vrai bottleneck (souvent une requête DB, pas une boucle). Optimiser là où le profiling montre un gain. Si le gain est < 10%, se demander si la complexité ajoutée le justifie.
23
+
24
+ ### Optimiser la moyenne
25
+ **Ce qu'on voit :** "la latence moyenne est de 200ms, c'est bon." Le P95 est à 8 secondes — 5% des utilisateurs attendent 8 secondes. Mais la moyenne est belle.
26
+ **Pourquoi c'est dangereux :** la moyenne est insensible aux outliers. 95% des requêtes à 50ms + 5% à 10s = moyenne de ~550ms. Tu regardes 550ms et tu penses "acceptable". Mais 5% de tes utilisateurs ont une expérience exécrable. Les percentiles existent pour cette raison précise.
27
+ **Faire plutôt :** P50 (médiane), P95, P99. Le P95 est l'expérience "normale dans le pire cas". Le P99 est l'expérience "vraiment mauvaise". Alerter et optimiser sur les percentiles, pas sur la moyenne.
28
+
29
+ ### Cache sans stratégie
30
+ **Ce qu'on voit :** `cache.set(key, data)` sans TTL. Le cache garde des données stales indéfiniment. Ou pire : le cache est invalidé à chaque écriture mais jamais rechargé (cache toujours vide).
31
+ **Pourquoi c'est dangereux :** un cache mal conçu est pire que pas de cache — il ajoute de la latence (aller-retour Redis) pour servir des données périmées ou pour ne jamais avoir de hit. Le hit rate est la métrique qui dit si ton cache sert à quelque chose.
32
+ **Faire plutôt :** TTL explicite basé sur la fraîcheur acceptable. Surveiller le hit rate — si < 50%, le cache est probablement mal configuré. Cache-aside pour les lectures, write-through pour les lectures après écriture.
33
+
34
+ ## Patterns
35
+ ### Performance budget
36
+ **Quand :** application web ou mobile.
37
+ **Comment :** définir des seuils dans la CI. JS bundle < 200KB, page weight < 1MB, LCP < 2.5s, TTI < 3s, P95 API < 500ms. Si la PR dépasse, bloquer. Le budget force la discipline — comme un budget financier, tu ne peux pas ajouter sans enlever ailleurs.
38
+
39
+ ### Slow query monitoring
40
+ **Quand :** toute application avec une base de données.
41
+ **Comment :** loguer toute requête > 100ms avec son EXPLAIN ANALYZE. Dashboard des slow queries. Alerte si une nouvelle slow query apparaît (requête qui était rapide avant, lente maintenant = probablement un index ou un volume de données). Chaque slow query est un ticket.