@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,103 @@
1
+ ---
2
+ name: validate-source-credibility
3
+ description: Scores information sources on credibility and freshness — official docs > maintainer blog > GitHub issue > StackOverflow > community forum > random blog. Flags stale content (> 12 months for fast-moving libs). Invoked during research synthesis to rank findings before trusting.
4
+ allowed-tools: WebFetch
5
+ context: fork
6
+ agent: researcher
7
+ ---
8
+
9
+ # validate-source-credibility — Rank sources by trust
10
+
11
+ ## What this covers
12
+ Meta-research skill #4 of 6. Not all sources are equal. Wrong information confidently presented causes downstream failures. This skill scores every finding before it influences code decisions.
13
+
14
+ ## Core principle
15
+ **Credibility is tiered, not binary.** A Tier-1 source (official docs) needs no validation. A Tier-4 source (random blog) is a hypothesis until cross-referenced.
16
+
17
+ ## Inputs
18
+
19
+ ```
20
+ SOURCE_URL: [URL of information source]
21
+ CLAIM: [what the source says]
22
+ TECHNOLOGY: [lib name]
23
+ VERSION: [version the claim is about]
24
+ ```
25
+
26
+ ## Credibility tiers
27
+
28
+ | Tier | Source | Trust |
29
+ |------|--------|-------|
30
+ | **1** | Official docs, GitHub release notes, source code | High — always prefer |
31
+ | **2** | Maintainer blog, maintainer GitHub discussion, conference talk | High for scope; possible bias |
32
+ | **3** | SO accepted (50+ upvotes), GitHub issue with maintainer comment, Reddit consensus | Medium — cross-reference |
33
+ | **4** | Random blog, low-upvoted SO, Medium article without credentials | Low — verify against Tier 1/2 |
34
+ | **5** | AI-generated content, old tutorials without authorship | Zero — flag, do not follow |
35
+
36
+ ## Freshness thresholds
37
+
38
+ | Library pace | Max age |
39
+ |-------------|---------|
40
+ | Fast (React, Next.js, Ktor, Tailwind) | 12 months |
41
+ | Medium (Rails, Django, Spring) | 18 months |
42
+ | Slow (C, SQL, git) | 36 months |
43
+ | Stable fundamentals | 5+ years |
44
+
45
+ ## Process
46
+
47
+ ### 1. Identify tier from URL + content
48
+
49
+ ### 2. Extract publication date
50
+
51
+ ### 3. Compute freshness (fresh / aging / stale)
52
+
53
+ ### 4. Score: Tier + Freshness → FULL / VERIFY / REJECT
54
+
55
+ ## Common patterns
56
+
57
+ ### Good credibility assessment
58
+
59
+ ```
60
+ ## SOURCE CREDIBILITY — https://blog.example.com/react-19-patterns
61
+
62
+ Tier: 4 (personal blog, no maintainer credential)
63
+ Freshness: aging — published 2025-11-08, 5 months old
64
+ Library pace: fast (React)
65
+
66
+ Credibility signals:
67
+ - Author unknown in React contributor list
68
+ - No upvote/engagement data available
69
+
70
+ Trust assessment: VERIFY — cross-reference with official docs before using
71
+
72
+ Recommendation: Do not trust alone. Verify claim "use() replaces useEffect" against react.dev.
73
+ ```
74
+
75
+ ### Bad credibility assessment
76
+
77
+ ```
78
+ Source looks reliable. Use it.
79
+ ```
80
+
81
+ Problems: no tier, no freshness check, no trust assessment.
82
+
83
+ ## Anti-patterns
84
+
85
+ - **Tier 4/5 trusted alone** — always cross-reference against Tier 1/2
86
+ - **Tier 1 overrides common sense** — if docs contradict source code for installed version, flag conflict
87
+ - **Age penalized unfairly** — stable fundamentals don't age. A 2017 article on TCP sockets is still correct.
88
+ - **Freshness = correctness** — a brand-new blog post can be wrong; an old maintainer article on stable API can be right
89
+ - **AI-generated content not detected** — boilerplate patterns, generic structure, no author credentials → suspect
90
+
91
+ ## How to verify
92
+
93
+ - [ ] Tier assigned (1-5)?
94
+ - [ ] Publication date extracted?
95
+ - [ ] Freshness assessed against library pace?
96
+ - [ ] Trust assessment given (FULL / VERIFY / REJECT)?
97
+ - [ ] Recommendation states how main session should treat this source?
98
+
99
+ ## When triggered
100
+
101
+ - By `synthesize-findings` when merging multi-source research
102
+ - On any finding from Tier 3/4/5 before it influences code decisions
103
+ - User request: "how reliable is this source?"
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: resilience
3
+ description: "Resilience — circuit breakers, retry with backoff, timeouts, bulkheads, graceful degradation. À charger quand on rend un système tolérant aux pannes."
4
+ ---
5
+
6
+ # Resilience
7
+
8
+ **Principe premier :** La résilience n'est pas "gérer les erreurs" — c'est concevoir le système pour qu'il continue à fonctionner (même en mode dégradé) quand ses dépendances tombent. Chaque dépendance externe va tomber un jour. La question n'est pas "est-ce que Redis est fiable ?" mais "que fait mon application quand Redis est down ?". Le circuit breaker n'est pas un pattern — c'est un réflexe : ne pas continuer à appeler un service qui ne répond pas.
9
+
10
+ ## Checklist
11
+ - [ ] Timeouts explicites sur tout appel externe : connect < 2s, read < 5s, request < 10s
12
+ - [ ] Circuit breaker sur chaque dépendance : échecs > N → circuit OPEN → fast fail
13
+ - [ ] Retry avec backoff exponentiel + jitter — pas de retry immédiat, max 3-5 tentatives
14
+ - [ ] Bulkhead : pools de connexions séparés par client/type de requête
15
+ - [ ] Fallback défini pour chaque point de défaillance : cache, defaults, degraded mode
16
+ - [ ] Chaos engineering : tester la résilience en production, pas en théorie
17
+
18
+ ## Anti-patterns
19
+ ### Retry sans backoff
20
+ **Ce qu'on voit :** `while (!ok) { try { call(); ok = true; } catch {} }` — retry immédiat en boucle.
21
+ **Pourquoi c'est dangereux :** thundering herd. Le service en difficulté reçoit 1000× plus de requêtes à cause des retries. L'incident s'aggrave. Un retry immédiat est une attaque DDoS contre soi-même.
22
+ **Faire plutôt :** backoff exponentiel avec jitter. 1s → 2s → 4s → 8s, max 5 tentatives. Le jitter (aléatoire ±25%) empêche la synchronisation des retries de tous les clients.
23
+
24
+ ### Pas de fallback
25
+ **Ce qu'on voit :** si Redis est down → 500 Internal Server Error. Le cache est devenu un point de défaillance unique.
26
+ **Pourquoi c'est dangereux :** une dépendance non-critique (cache, analytics, recommandations) fait tomber tout le service. Le client voit une erreur pour une fonctionnalité qui aurait pu fonctionner sans cette dépendance.
27
+ **Faire plutôt :** si cache down → servir depuis la DB (plus lent mais fonctionnel). Si analytics down → logger localement et réessayer plus tard. Chaque dépendance a un fallback explicite.
28
+
29
+ ### Timeout = 60 secondes
30
+ **Ce qu'on voit :** `http.get(url, { timeout: 60000 })`. L'utilisateur attend 60s.
31
+ **Pourquoi c'est dangereux :** les threads/workers sont bloqués. Le pool s'épuise. L'app devient non-réactive. Un timeout trop long transforme une défaillance partielle en outage total.
32
+ **Faire plutôt :** timeouts agressifs. Connect < 2s, read < 5s. L'utilisateur préfère un échec rapide qu'une attente infinie. Fast fail > slow timeout.
33
+
34
+ ## Patterns
35
+ ### Circuit Breaker
36
+ **Quand :** toute communication avec une dépendance externe.
37
+ **Comment :** CLOSED (normal) → OPEN après N échecs consécutifs → HALF_OPEN après timeout → CLOSED si succes. En OPEN, les appels sont rejetés immédiatement (pas de tentative inutile).
38
+
39
+ ### Bulkhead
40
+ **Quand :** ressources partagées entre différents appels/clients.
41
+ **Comment :** pool de connexions séparé par client. Si un client sature son pool, les autres ne sont pas affectés. Comme les cloisons étanches d'un navire — une voie d'eau ne coule pas le bateau.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: serverless
3
+ description: "Serverless — fonctions comme unites de deploiement, cold starts, concurrency, API Gateway, Step Functions, cout a la requete. A charger quand on utilise des fonctions serverless."
4
+ ---
5
+
6
+ # Serverless
7
+
8
+ **Principe premier :** Le serverless n'est pas "pas de serveur" — c'est "le serveur n'est pas ton probleme". Tu echange le controle contre la simplicite operationnelle. Le piege : tu ne controles plus le runtime, la memoire, le reseau, le systeme de fichiers. Chaque hypothese que tu fais sur l'execution ("le /tmp existe", "l'IP est stable", "le process survit entre deux requetes") est une source de bug. Le serverless recompense l'architecture stateless et punit le stateful. Le cout est a la requete — une fonction inefficace coute de l'argent a chaque appel, pas juste du CPU.
9
+
10
+ ## Checklist
11
+ - [ ] Les fonctions sont stateless — pas de donnees persistees dans le filesystem local (/tmp est ephemere)
12
+ - [ ] Les connexions DB/Redis sont hors du handler (global scope, reutilisees entre invocations)
13
+ - [ ] Le timeout est configure explicitement (3s pour API, 30s max pour async) — pas de timeout infini
14
+ - [ ] La memoire est dimensionnee correctement (plus de RAM = plus de CPU, mais plus de cout)
15
+ - [ ] Les cold starts sont mesures (P50/P95) et optimises (bundling, provisioned concurrency si necessaire)
16
+ - [ ] API Gateway / load balancer a un health check independant de la fonction
17
+ - [ ] Les fonctions ont un dead letter queue pour les evenements non traites
18
+
19
+ ## Anti-patterns
20
+ ### Fonction monolithe
21
+ **Ce qu'on voit :** une seule Lambda/Cloud Function qui gere toutes les routes. 500MB de code, 3s de cold start. "C'est un microservice."
22
+ **Pourquoi c'est dangereux :** le cold start est proportionnel a la taille du code. Le deploiement est tout-ou-rien. Le debugging est un cauchemar. C'est un monolithe avec les inconvenients du serverless (cold starts, timeouts) sans les benefices (isolation, deploiement independant).
23
+ **Faire plutot :** une fonction par endpoint/operation. Chaque fonction est independante : son propre code, son propre deploiement, son propre timeout. Si une fonction est lente, les autres ne sont pas affectees.
24
+
25
+ ### State cache dans le handler
26
+ **Ce qu'on voit :** `let connection; export const handler = async (event) => { if (!connection) connection = await createDbConnection(); ... }` — le test unitaire passe, la prod echoue aleatoirement.
27
+ **Pourquoi c'est dangereux :** la connection est reutilisee entre invocations mais pas entre cold starts. Le comportement depend de l'etat du container (warm/cold), ce qui est non deterministe. Pire : si la connection est stales (timeout serveur), elle echoue silencieusement.
28
+ **Faire plutot :** initialiser dans le global scope, AVANT le handler. Verifier la sante de la connexion a chaque invocation. Accepter que les cold starts arrivent et les monitoriser.
29
+
30
+ ### Serverless pour tout
31
+ **Ce qu'on voit :** toute l'architecture est en serverless. Y compris un job qui tourne 24/7, un websocket qui reste ouvert 2h, une DB de 10 To.
32
+ **Pourquoi c'est dangereux :** le serverless est optimal pour les charges sporadiques et les pics. Pour une charge constante, le cout par requete est superieur a un serveur. Les timeouts (15 min Lambda, 60 min Cloud Functions) rendent certains workloads impossibles. Les websockets sur serverless = cout eleve et latence variable.
33
+ **Faire plutot :** serverless pour les API, les traitements asynchrones, les cron jobs. Serveur/container pour les charges constantes, les connexions longues, les traitements lourds. Hybride : ce n'est pas l'un ou l'autre.
34
+
35
+ ## Patterns
36
+ ### Global scope initialization
37
+ **Quand :** toute fonction qui utilise une connexion externe (DB, Redis, API client).
38
+ **Comment :** initialiser les clients hors du handler. Le runtime reutilise le container pour plusieurs invocations — le code hors handler n'est execute qu'au cold start. SDK clients, connexions, configuration : tout dans le global scope. Le handler ne fait que le metier.
39
+
40
+ ### Step Functions pour l'orchestration
41
+ **Quand :** workflow multi-etapes (paiement → stock → email → facture).
42
+ **Comment :** chaque etape est une fonction separee. Step Functions gere les transitions, les retries, les timeouts, la compensation (Saga pattern). Le workflow est visible dans la console, chaque etape est monitorisee independamment.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: servers
3
+ description: "Servers — reverse proxy comme défense périmétrique, TLS termination, process management, OS hardening. À charger quand on configure des serveurs."
4
+ ---
5
+
6
+ # Servers
7
+
8
+ **Principe premier :** Un serveur n'est pas la machine où tourne l'app — c'est la première ligne de défense. Ne jamais exposer une application directement. Toujours un reverse proxy devant qui gère TLS, rate limiting, buffering. L'application ne doit voir que du trafic propre et autorisé. Le serveur doit survivre à un reboot, un crash applicatif, et un pic de trafic sans intervention humaine.
9
+
10
+ ## Checklist
11
+ - [ ] Reverse proxy devant l'application (Nginx/Caddy/Traefik) — jamais d'exposition directe
12
+ - [ ] TLS 1.3 avec certificats auto-renouvelés (LetsEncrypt/cert-manager)
13
+ - [ ] Process manager avec restart automatique (systemd) — pas de `node server.js &`
14
+ - [ ] Health check endpoint utilisé par le load balancer (liveness ≠ readiness)
15
+ - [ ] Firewall : seuls les ports 443 et 80 (redirect) sont ouverts, SSH restreint
16
+ - [ ] Log rotation configurée avec retention max — pas de disque plein par les logs
17
+
18
+ ## Anti-patterns
19
+ ### Application directement exposée
20
+ **Ce qu'on voit :** `app.listen(443)` — l'app écoute directement sur le port public. Pas de proxy.
21
+ **Pourquoi c'est dangereux :** pas de buffering → un client lent bloque un worker. Pas de rate limiting → pas de protection DDoS basique. Pas de cache statique → chaque requête touche l'app. Le reverse proxy est une couche de défense gratuite.
22
+ **Faire plutôt :** Nginx/Caddy en frontal. Il gère TLS, compression, cache statique, rate limiting. L'app écoute sur localhost:3000 et ne voit que du trafic filtré.
23
+
24
+ ### Redémarrage manuel
25
+ **Ce qu'on voit :** `node server.js` lancé dans un screen/tmux. Crash → app down jusqu'à intervention humaine.
26
+ **Pourquoi c'est dangereux :** tout process crashe un jour. OOM, segfault, exception non catchée. Sans restart automatique, chaque crash = outage non borné. À 3h du matin, personne ne relance.
27
+ **Faire plutôt :** systemd avec `Restart=always` et `RestartSec=5`. Le process manager relance en secondes.
28
+
29
+ ### Logs sans rotation
30
+ **Ce qu'on voit :** `app.log` qui grossit depuis 6 mois. 50 Go. Le disque se remplit.
31
+ **Pourquoi c'est dangereux :** disque plein = tout tombe. L'app ne peut plus écrire, la DB s'arrête. L'outage par manque d'espace disque est le plus évitable de tous.
32
+ **Faire plutôt :** logrotate avec retention 30 jours. Alerte si espace disque < 20%. Les logs sont streamés vers un système centralisé, pas stockés localement.
33
+
34
+ ## Patterns
35
+ ### Reverse proxy
36
+ **Quand :** toute application web en production.
37
+ **Comment :** Nginx/Caddy en frontal. TLS termination, compression, cache statique, rate limiting. L'applicatif derrière sur localhost uniquement.
38
+
39
+ ### Health check
40
+ **Quand :** load balancer ou orchestrateur devant l'app.
41
+ **Comment :** `GET /health` → `{"status":"ok","uptime":3600,"db":"connected"}`. Vérifié toutes les 10s. 3 échecs → retirer l'instance du pool.
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: sql
3
+ description: "SQL — EXPLAIN ANALYZE comme discipline, CTE & window functions, requêtes N+1, transactions courtes, connection pooling. À charger quand on écrit ou optimise des requêtes SQL."
4
+ ---
5
+
6
+ # SQL
7
+
8
+ **Principe premier :** Le SQL n'est pas un langage de requête — c'est un langage déclaratif qui décrit CE QUE tu veux, pas COMMENT l'obtenir. Le planificateur de la DB décide du comment. Ton job n'est pas d'écrire "la bonne requête" — c'est d'écrire une requête que le planificateur peut optimiser. La discipline fondamentale est donc : toujours vérifier ce que le planificateur a fait (EXPLAIN ANALYZE). Sans ça, tu codes à l'aveugle. Un index n'existe que si le planificateur l'utilise.
9
+
10
+ ## Checklist
11
+ - [ ] EXPLAIN ANALYZE dans la PR pour toute requête non-triviale — pas après la mise en prod
12
+ - [ ] Pas de `SELECT *` sauf si tu as VRAIMENT besoin de toutes les colonnes
13
+ - [ ] Les JOINs sont vérifiés : chaque condition de JOIN a un index des deux côtés
14
+ - [ ] Pas de N+1 — les données liées sont fetchées en une requête (JOIN, IN, ou LATERAL)
15
+ - [ ] Les transactions sont aussi courtes que possible — tout le calcul est fait avant le BEGIN
16
+ - [ ] Connection pooling : PgBouncer (transaction mode) ou équivalent entre l'app et PostgreSQL
17
+
18
+ ## Anti-patterns
19
+ ### N+1 queries
20
+ **Ce qu'on voit :** `for (const user of users) { orders = await db.query('SELECT * FROM orders WHERE user_id = $1', [user.id]) }`. 100 users = 101 requêtes.
21
+ **Pourquoi c'est dangereux :** le N+1 est le tueur silencieux de performance. Chaque requête a une latence réseau (0.5ms en local, 5ms en cloud). 1000 users = 5 secondes juste en overhead réseau. Et le pire : la DB pourrait répondre en 50ms avec un JOIN.
22
+ **Faire plutôt :** `SELECT * FROM orders WHERE user_id = ANY($1)` avec un tableau d'IDs. Ou JOIN. Toujours regarder les boucles qui contiennent des requêtes DB — c'est le pattern N+1.
23
+
24
+ ### EXPLAIN jamais fait
25
+ **Ce qu'on voit :** la requête est lente en production. On ajoute un index "au pif" sur une colonne qui semblait importante. La requête est toujours lente — l'index n'est pas utilisé.
26
+ **Pourquoi c'est dangereux :** sans EXPLAIN ANALYZE, tu ne sais pas ce que la DB fait vraiment. Seq Scan ? Index Scan ? Nested Loop ? Hash Join ? Chaque choix du planificateur a un impact 100-1000× sur la performance. Deviner l'index est du gaspillage.
27
+ **Faire plutôt :** `EXPLAIN (ANALYZE, BUFFERS) SELECT ...` → regarder le plan. Seq Scan sur grosse table → index. Nested Loop sur 100K×100K → Hash Join. L'index se met là où le plan montre un goulot, pas là où "ça semble logique".
28
+
29
+ ### Transaction longue
30
+ **Ce qu'on voit :** `BEGIN; calculApplicatif(); query1(); appelAPIExterne(); query2(); COMMIT;` L'appel API prend 2 secondes.
31
+ **Pourquoi c'est dangereux :** la transaction garde des locks (RowExclusive, ShareLock) pendant toute sa durée. Toutes les modifications concurrentes sur les mêmes rows sont bloquées. 2 secondes de blocage → file d'attente → timeout → erreurs en cascade.
32
+ **Faire plutôt :** tout le calcul, les appels API, la validation métier sont faits AVANT le BEGIN. La transaction ne contient QUE les requêtes DB. Durée < 100ms. Si un appel externe est nécessaire au milieu → reconsidérer le design.
33
+
34
+ ## Patterns
35
+ ### CTE (Common Table Expression)
36
+ **Quand :** requête complexe avec des étapes intermédiaires.
37
+ **Comment :** `WITH active_users AS (SELECT id FROM users WHERE last_login > now() - interval '30 days'), user_orders AS (SELECT ...) SELECT ... FROM active_users JOIN user_orders ...`. Le CTE nomme chaque étape — bien plus lisible qu'une soupe de sous-requêtes. `MATERIALIZED` ou non selon que le CTE est réutilisé.
38
+
39
+ ### Window functions
40
+ **Quand :** classement, cumuls, ou comparaison entre rows sans perdre la granularité.
41
+ **Comment :** `ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at)` pour le premier/dernier par groupe. `LAG(price) OVER (PARTITION BY product ORDER BY date)` pour la variation. Pas de self-JOIN coûteux.
42
+
43
+ ### Connection pooling
44
+ **Quand :** toute application en production avec PostgreSQL.
45
+ **Comment :** PgBouncer en transaction mode. L'app se connecte à PgBouncer (local), PgBouncer multiplexe sur PostgreSQL (peu de connexions). 1000 clients → 20 connexions DB. Évite le fork() par connexion de PostgreSQL.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: supply-chain
3
+ description: "Supply Chain Security — dépendances comme surface d'attaque, lockfile integrity, SBOM, SLSA provenance, signed commits. À charger quand on sécurise la chaîne d'approvisionnement."
4
+ ---
5
+
6
+ # Supply Chain Security
7
+
8
+ **Principe premier :** Chaque dépendance est une backdoor potentielle. La sécurité de la supply chain ne consiste pas à auditer chaque package — c'est impossible. Elle consiste à réduire la surface d'attaque (moins de dépendances), garantir la reproductibilité (lockfiles, pinning), et créer de la traçabilité (SBOM, provenance). Le jour où une CVE sort (et elle sortira), tu dois pouvoir répondre en < 1h à la question : "quels services utilisent ce package ?"
9
+
10
+ ## Checklist
11
+ - [ ] Les dépendances sont épinglées (version exacte ou lockfile commité) — build reproductible
12
+ - [ ] Le nombre de dépendances est surveillé comme une métrique de risque — chaque ajout est justifié
13
+ - [ ] SBOM généré à chaque build (SPDX ou CycloneDX) et requêtable en cas d'incident
14
+ - [ ] SLSA niveau 2 minimum : build isolé, provenance attestée, artefacts signés
15
+ - [ ] Les dépendances non maintenues sont identifiées et remplacées proactivement
16
+ - [ ] Les signatures de commits et tags sont vérifiées — pas de "verified" sur un seul commit sur 100
17
+
18
+ ## Anti-patterns
19
+ ### Dépendance non épinglée
20
+ **Ce qu'on voit :** `"express": "^4.18.0"` dans package.json, pas de lockfile dans le repo. Chaque `npm install` peut installer une version différente.
21
+ **Pourquoi c'est dangereux :** un build non reproductible est un build non auditable. Si un attaquant compromet une version mineure de express, ton build l'installe silencieusement. Le hash de ton artefact change sans que tu saches pourquoi.
22
+ **Faire plutôt :** lockfile commité dans le repo. `npm ci` (pas `npm install`) dans la CI. Version exacte pinnée pour les dépendances critiques. Le lockfile est ta déclaration de ce qui tourne en production — traite-le comme tel.
23
+
24
+ ### Dépendance comme choix gratuit
25
+ **Ce qu'on voit :** `npm install left-pad` pour une fonction de 11 lignes. `npm install is-odd` pour `n % 2 === 1`. 1500 dépendances au total.
26
+ **Pourquoi c'est dangereux :** chaque dépendance est un vecteur d'attaque et une dette de maintenance. `event-stream` (2018) a été compromis pour voler des bitcoins. `ua-parser-js` (2021) a été infecté par un malware. Plus tu as de dépendances, plus ta surface d'attaque est grande.
27
+ **Faire plutôt :** évaluer chaque dépendance avant de l'ajouter : est-ce que ça fait plus de 50 lignes de logique non-triviale ? Est-ce maintenu (dernier commit < 6 mois) ? Combien de maintainers ? Préférer la stdlib ou copier 10 lignes (attribuées) plutôt qu'une dépendance pour une fonction triviale.
28
+
29
+ ### SBOM inutilisable en incident
30
+ **Ce qu'on voit :** un SBOM est généré, stocké dans un artefact de build que personne ne sait requêter. Le jour J, retrouver les services affectés prend 4h.
31
+ **Pourquoi c'est dangereux :** un SBOM qui n'est pas utilisable en incident est du théâtre de sécurité. Log4Shell a montré que les équipes qui avaient un SBOM requêtable ont patché en heures. Les autres en semaines.
32
+ **Faire plutôt :** SBOM versionné, stocké dans un registre central requêtable. Test d'audit trimestriel : "Simule une CVE sur le package X. Chronomètre le temps pour lister tous les services affectés." Si > 10 min, le processus est cassé.
33
+
34
+ ## Patterns
35
+ ### SBOM comme produit
36
+ **Quand :** toute application en production.
37
+ **Comment :** génération automatisée via Syft/Trivy dans la CI. Format SPDX ou CycloneDX. Stockage dans un registre (Dependency-Track, OWASP). API pour requêter "quels services utilisent log4j ?" en une requête. Le SBOM est un livrable, pas un sous-produit.
38
+
39
+ ### SLSA provenance
40
+ **Quand :** consommateurs qui ont besoin de vérifier l'origine de l'artefact.
41
+ **Comment :** SLSA niveau 2 : build isolé (pas d'accès au réseau arbitraire), provenance signée (attestation du build system). Le consommateur vérifie la signature avant d'utiliser l'artefact. Le but : empêcher qu'un build compromis produise un artefact qui a l'air légitime.
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: system-design
3
+ description: "System Design — estimation back-of-envelope, CAP theorem, trade-offs, scalability patterns, load balancing, caching layers. A charger quand on concoit un nouveau service."
4
+ ---
5
+
6
+ # System Design
7
+
8
+ **Principe premier :** Le system design n'est pas "choisir les bonnes technologies" — c'est identifier les contraintes et les accepter. Chaque decision d'architecture est un trade-off : consistency vs availability, latence vs throughput, simplicite vs flexibilite. Si tu ne peux pas nommer ce que tu sacrifies, tu n'as pas vraiment designe. La competence cle n'est pas de connaitre les patterns — c'est de savoir estimer (back-of-envelope) pour ne pas resoudre un probleme qui n'existe pas.
9
+
10
+ ## Checklist
11
+ - [ ] Estimation back-of-envelope faite avant tout choix d'architecture (req/s, stockage, bande passante)
12
+ - [ ] Le CAP theorem est arbitre : ce systeme doit-il etre CP ou AP ? Pourquoi ?
13
+ - [ ] Chaque couche a une strategie de scale (vertical, horizontal, ou sharding)
14
+ - [ ] Les single points of failure sont identifies et elimines (ou assumes avec un plan de recovery)
15
+ - [ ] Le caching est place la ou il reduit la latence, pas la ou il est facile a implementer
16
+ - [ ] Les operations lourdes sont async (file d'attente, workers) — l'utilisateur ne bloque pas
17
+ - [ ] Le plan de capacity planning existe : a quel seuil on passe au niveau superieur ?
18
+
19
+ ## Trade-offs : les 3 choix structurants
20
+
21
+ ### SQL vs NoSQL
22
+
23
+ | | SQL (PostgreSQL, MySQL) | NoSQL (DynamoDB, MongoDB) |
24
+ |--|-------------------------|---------------------------|
25
+ | **Modele** | Schema fixe, relations, JOINs | Schema flexible, pas de JOINs |
26
+ | **Scale** | Vertical puis read replicas | Horizontal natif (sharding) |
27
+ | **Quand choisir** | Relations complexes, transactions ACID, reporting | Acces par cle connu, schema variable, scale horizontal obligatoire |
28
+ | **Piege** | Les migrations deviennent le bottleneck | Tu decouvres que t'as besoin de JOINs → impossible |
29
+ | **Ne JAMAIS faire** | `SELECT * FROM orders JOIN ... JOIN ... JOIN ...` sur 10M rows | Utiliser NoSQL "au cas ou" sans avoir mesure le besoin de scale |
30
+
31
+ ### Sync vs Async
32
+
33
+ | | Sync (HTTP/gRPC) | Async (queues/events) |
34
+ |--|------------------|----------------------|
35
+ | **Consistance** | Immediate (le client sait tout de suite) | Eventuelle (le client sait plus tard) |
36
+ | **Couplage** | Le caller attend le callee | Decouple temporellement |
37
+ | **Quand choisir** | L'utilisateur attend la reponse | Operation lourde, notification, propagation |
38
+ | **Piege** | Le timeout tue tout (si B est lent, A est lent) | Debugging : ou est l'event ? Qui l'a traite ? |
39
+
40
+ ### Monolithe vs Microservices
41
+
42
+ | | Monolithe | Microservices |
43
+ |--|----------|--------------|
44
+ | **Deploy** | 1 artefact | N artefacts independants |
45
+ | **Scale** | Tout ou rien | Par service (le checkout scale, pas l'auth) |
46
+ | **Complexite** | Dans le code (couplage) | Dans le reseau (latence, serialisation, erreurs) |
47
+ | **Quand choisir** | Equipe < 20, domaine stable, pas de besoin de scale independant | Equipes autonomes (> 5 equipes), modules qui scalent differemment |
48
+ | **Piege** | Le monolithe devient un "big ball of mud" (pas de frontieres internes) | 12 services pour 3 devs : le cout de coordination > benefices |
49
+ | **Regle** | Commencer monolithe modulaire. Extraire en service UNIQUEMENT quand la douleur est prouvee. |
50
+
51
+ ## Anti-patterns
52
+ ### Designer pour Google
53
+ **Ce qu'on voit :** sharding, event sourcing, CQRS, 12 microservices — pour 100 utilisateurs.
54
+ **Pourquoi c'est dangereux :** la complexite que tu construis aujourd'hui est la dette que tu paieras demain. Chaque couche ajoute des points de defaillance.
55
+ **Faire plutot :** estimation back-of-envelope. "100 req/s x 50ms = 5 workers suffisent. Une DB avec read replicas tient 10 000 req/s. Pas besoin de sharding avant 100k req/s." Le design evolue avec la charge.
56
+
57
+ ### Single point of failure ignore
58
+ **Ce qu'on voit :** un load balancer, une DB, une region. "On verra quand ca tombera."
59
+ **Pourquoi c'est dangereux :** tout tombe. Un SPOF qui tombe = 100% du service down.
60
+ **Faire plutot :** redondance sur chaque couche. Multi-AZ, replicas, failover automatique. Si un composant ne peut pas etre redondant, documenter explicitement pourquoi.
61
+
62
+ ### Pas d'estimation avant de coder
63
+ **Ce qu'on voit :** un endpoint cree sans savoir combien de req/s il va prendre. En production, ca s'effondre.
64
+ **Pourquoi c'est dangereux :** sans estimation, le choix d'architecture est arbitraire. SQL vs NoSQL, sync vs async — ces decisions dependent des ordres de grandeur.
65
+ **Faire plutot :** estimation en 5 min : req/s x pics, taille payload x volume, latence acceptable. Des ordres de grandeur. Si les ordres changent d'un facteur 10, le design change.
66
+
67
+ ## Patterns
68
+ ### Back-of-envelope estimation
69
+ **Quand :** avant tout choix d'architecture.
70
+ **Comment :** 3 calculs. (1) Throughput : req/s / temps de traitement = workers necessaires. (2) Storage : req/s x taille par req x retention = volume disque. (3) Network : req/s x taille de reponse = bande passante. Toujours x10 pour la marge. Si les chiffres sont petits, rester simple.
71
+
72
+ **Mise en place :** (1) Lister les endpoints/operations. (2) Estimer les req/s en pic. (3) Multiplier par la taille de payload. (4) Verifier que chaque couche (LB, app, DB, cache) tient ces chiffres. (5) Documenter les seuils de passage a l'echelle superieure (ex: a 1000 req/s → add read replica).
73
+
74
+ ### Consistent hashing
75
+ **Quand :** sharding avec redistribution minimale quand on ajoute/supprime un nœud.
76
+ **Comment :** ring de hash. Chaque cle → premier nœud dans le sens horaire. Ajout d'un nœud ne redistribue que les cles voisines (pas tout le keyspace).
77
+
78
+ **Mise en place :** (1) Choisir une fonction de hash (SHA-256, MD5 tronque). (2) Placer les nœuds sur le ring. (3) Pour chaque cle, hash → premier nœud dans le sens horaire. (4) Pour la redondance, chaque cle va sur N nœuds consecutifs (replication). (5) Ajouter/supprimer un nœud ne deplace que ~K/N cles. Utilise par CDN, caches distribues, partitions DB.
79
+
80
+ ### Backpressure
81
+ **Quand :** un producteur est plus rapide que le consommateur.
82
+ **Comment :** refuser explicitement (429/503) plutot qu'accepter et timeout. Rate limiting a l'entree. Queue avec capacite max.
83
+
84
+ **Mise en place :** (1) Definir la capacite max (ex: 1000 requetes concurrentes). (2) Rate limiter a l'entree (token bucket, sliding window). (3) Queue bornee (taille max, pas infinie). (4) Si file pleine → 429. (5) Le client retry avec exponential backoff + jitter. La backpressure se propage — si le worker est plein, l'API refuse, le client ralentit.
85
+
86
+ ### Cache layers (ou placer le cache)
87
+ **Quand :** latence a reduire sur un chemin critique.
88
+ **Comment :** cache navigateur (Cache-Control headers) → CDN (edge cache) → cache applicatif (Redis) → DB. Chaque couche reduit la latence et la charge sur la couche suivante.
89
+ - **Avantages :** reduction drastique de la latence (DB: 10ms, Redis: 1ms, CDN: 0ms pour le client)
90
+ - **Desavantages :** stale data, invalidation complexe, memoire = cout
91
+ - **Mise en place :** (1) Identifier la hot path. (2) Mesurer la latence actuelle par couche. (3) Ajouter le cache le plus proche du client d'abord (CDN > Redis > local). (4) Definir TTL = fraicheur acceptable. (5) Monitorer hit rate > 80%.
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: tech-leadership
3
+ description: "Tech Leadership — ADR, RFC, architecture reviews, dette technique, mentoring, estimation, roadmap technique. A charger quand on fait du leadership technique."
4
+ ---
5
+
6
+ # Tech Leadership
7
+
8
+ **Principe premier :** Le leadership technique n'est pas "le dev le plus senior decide" — c'est creer un environnement ou les bonnes decisions emergent de l'equipe. Le tech lead n'est pas un architecte omniscient qui dicte les solutions — c'est un jardinier qui cree les conditions pour que les bonnes pratiques poussent. Les deux livrables principaux sont les ADR (Architecture Decision Records) qui capturent le contexte et le pourquoi des decisions, et la strategie de dette technique (toute equipe a de la dette — la question est de savoir laquelle et a quel prix). Le technicien resout les problemes ; le tech lead rend l'equipe capable de resoudre les problemes sans lui.
9
+
10
+ ## Checklist
11
+ - [ ] Les decisions techniques sont documentees en ADR (contexte, alternatives considerees, decision, consequences)
12
+ - [ ] La dette technique est suivie, budgetee (ex: 20% du sprint), et communiquee aux stakeholders
13
+ - [ ] Les RFC sont le processus standard pour les changements majeurs (> 2 semaines d'effort)
14
+ - [ ] L'estimation est basee sur l'historique (cycle time, throughput) — pas sur des jours/homme devines
15
+ - [ ] Les revues d'architecture sont regulieres (mensuelles) avec des criteres objectifs
16
+ - [ ] Le mentoring est structure : chaque dev junior a un plan de progression avec objectifs mesurables
17
+ - [ ] La roadmap technique est alignee avec la roadmap produit — pas deux planifications paralleles
18
+
19
+ ## Anti-patterns
20
+ ### Tech lead = seul decideur
21
+ **Ce qu'on voit :** le tech lead prend toutes les decisions seul. "Je connais le systeme, faites ce que je dis." L'equipe execute sans comprendre.
22
+ **Pourquoi c'est dangereux :** goulot d'etranglement decisionnel. L'equipe devient passive — "je fais ce que le lead dit". Le lead devient le bus factor = 1. Quand il part, la connaissance part avec lui. Les decisions ne sont pas contraintes parce que personne ne les conteste.
23
+ **Faire plutot :** decisions via RFC. L'auteur propose, l'equipe review, le lead approuve ou demande des changements. Le lead est un editeur, pas un auteur. Les decisions sont documentees (ADR) pour que le contexte survive au lead.
24
+
25
+ ### Dette technique = tabou
26
+ **Ce qu'on voit :** l'equipe sait qu'il y a de la dette. Personne n'en parle aux stakeholders. Un jour, tout explose et le sprint "refactoring urgent" dure 3 mois.
27
+ **Pourquoi c'est dangereux :** la dette technique non communiquee est une bombe a retardement. Les stakeholders ne comprennent pas pourquoi "une feature simple prend 3 semaines". La confiance s'erode. L'equipe est en mode pompier permanent.
28
+ **Faire plutot :** la dette technique est un choix economique, pas une honte. La quantifier ("ce module coute 2x plus cher a modifier que la moyenne"). La presenter aux stakeholders comme un risque avec un cout. Budgeter 20% du sprint pour la reduction de dette. Montrer le ROI : "apres ce refactoring, les features sur ce module seront 2x plus rapides".
29
+
30
+ ### Estimation = souhait
31
+ **Ce qu'on voit :** "c'est 3 jours" — base sur rien. Les estimations sont systematiquement x2-x3. Les deadlines sont basees sur les estimations et deviennent des engagements.
32
+ **Pourquoi c'est dangereux :** l'estimation n'est pas un engagement, mais les stakeholders l'entendent comme tel. Le cycle se repete : estimation optimiste → sous-performance percue → pression → estimation encore plus optimiste pour compenser → burn-out.
33
+ **Faire plutot :** estimer en probabilites : "50% de chances en 3 jours, 90% en 7 jours." Utiliser l'historique (cycle time reel, pas estime). Separer estimation (combien de temps) et engagement (quand c'est livre). L'engagement vient apres l'exploration, pas avant.
34
+
35
+ ## Patterns
36
+ ### ADR (Architecture Decision Record)
37
+ **Quand :** toute decision architecturale non triviale.
38
+ **Comment :** format standard : Titre, Contexte (pourquoi maintenant), Decision (ce qu'on a decide), Alternatives considerees, Consequences (positives et negatives). Fichier `docs/adrs/NNNN-title.md`. Les ADR documentent le POURQUOI, pas juste le QUOI. Un nouveau membre peut lire les ADR et comprendre l'histoire de l'architecture.
39
+
40
+ ### RFC (Request for Comments)
41
+ **Quand :** changement qui affecte > 1 equipe ou > 2 semaines d'effort.
42
+ **Comment :** document de 2-4 pages. Sections : Motivation, Design propose, Alternatives, Impact (migration, cout, risques). Review period : 3-5 jours. L'auteur n'est pas le decideur — l'equipe (ou les equipes) commentent, le lead tranche. La decision est capturee en ADR.
43
+
44
+ ### Probabilistic estimation
45
+ **Quand :** estimation d'une tache de > 1 jour.
46
+ **Comment :** "J'ai 50% de confiance que ca prendra X jours, 90% que ca prendra Y jours." Le ratio Y/X mesure l'incertitude. Si Y > 3X → l'incertitude est trop grande, faire un spike pour reduire. L'estimation est basee sur des taches similaires passees (historique), pas sur l'intuition.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: testing
3
+ description: "Testing — RED-GREEN-REFACTOR, test pyramid, testing behavior not implementation, FIRST principles, flaky test quarantine. À charger quand on écrit ou planifie des tests."
4
+ ---
5
+
6
+ # Testing
7
+
8
+ **Principe premier :** Les tests ne sont pas là pour prouver que le code marche — ils sont là pour te permettre de changer le code sans peur. Un test qui ne survit pas à un refactoring n'est pas un test, c'est un otage. Le but ultime n'est pas 100% de couverture — c'est la confiance : si les tests passent, je peux déployer. Si tu ne peux pas déployer après un test vert, les tests ont échoué, pas le code.
9
+
10
+ ## Checklist
11
+ - [ ] RED (test échoue) → GREEN (passe) → REFACTOR — dans cet ordre, toujours
12
+ - [ ] Les tests testent le comportement observable, pas l'implémentation interne
13
+ - [ ] Test pyramid : 70% unitaires, 20% intégration, 10% E2E — pas de pyramide inversée
14
+ - [ ] Chaque test est isolé — pas d'ordre d'exécution, pas de state partagé, pas de dépendance
15
+ - [ ] Les tests sont FIRST : Fast, Isolated, Repeatable, Self-validating, Timely
16
+ - [ ] Flaky test detection : > 2% de flaky → quarantaine automatique → fix ou delete dans le sprint
17
+
18
+ ## Anti-patterns
19
+ ### Tester l'implémentation
20
+ **Ce qu'on voit :** test qui mock `repository.findById()` et vérifie qu'il est appelé avec les bons arguments. Le test sait QUELLES méthodes le code appelle, pas ce que le code produit.
21
+ **Pourquoi c'est dangereux :** le test est couplé à l'implémentation. Tu refactores en inline le `findById()` → le test casse alors que le comportement est identique. Ces tests ne donnent PAS la confiance pour refactorer — ils empêchent le refactoring.
22
+ **Faire plutôt :** tester le comportement observable. Input → output. "Given un utilisateur avec id 123, when GET /users/123, then retourne {name, email}". Peu importe si le handler appelle un service ou un repository.
23
+
24
+ ### Mock absolument tout
25
+ **Ce qu'on voit :** DB mockée, Redis mocké, filesystem mocké, horloge mockée. Le test unitaire passe, le test d'intégration n'existe pas. Premier déploiement → explosion.
26
+ **Pourquoi c'est dangereux :** les mocks mentent. Un mock Redis ne vérifie pas le format de la clé. Un mock DB ne vérifie pas la contrainte UNIQUE. Le test passe mais le code est cassé en condition réelle. C'est la fausse confiance — pire que pas de confiance.
27
+ **Faire plutôt :** mocker les frontières lentes/non-déterministes (appels HTTP externes, emails). Tester avec une vraie DB en intégration (testcontainers, pg_tmp). La DB est le composant le plus important à tester réellement.
28
+
29
+ ### Test flaky toléré
30
+ **Ce qu'on voit :** "ce test faille parfois, relance le job". Le pipeline passe au 3ème rerun. Le flaky rate est de 5% mais personne ne le mesure.
31
+ **Pourquoi c'est dangereux :** chaque test flaky érode la confiance dans le pipeline. Quand le rouge ne veut plus dire "bug", les vrais bugs passent. L'équipe développe un réflexe "rerun" au lieu de "investigate". C'est la mort lente de la CI.
32
+ **Faire plutôt :** quarantaine automatique. Flaky > 2% → test déplacé dans une suite séparée. Le pipeline principal reste strict (vert = ok, rouge = bug). La quarantaine est prioritaire — chaque test est fixé, réécrit, ou supprimé.
33
+
34
+ ## Patterns
35
+ ### Test pyramid
36
+ **Quand :** toute suite de tests.
37
+ **Comment :** base large de tests unitaires (rapides, isolés, nombreux). Milieu de tests d'intégration (DB réelle, API réelle). Sommet étroit de tests E2E (parcours critiques). Si la pyramide s'inverse (beaucoup d'E2E, peu d'unitaires), le feedback est lent et le debugging est coûteux.
38
+
39
+ ### FIRST principles
40
+ **Quand :** écrire chaque test.
41
+ **Comment :** Fast (< 5ms unitaire, < 100ms intégration), Isolated (pas d'ordre), Repeatable (même résultat à chaque run), Self-validating (assertion, pas de log à vérifier manuellement), Timely (écrit AVANT le code — RED first).
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: tracing
3
+ description: "Tracing — OpenTelemetry, distributed traces, spans, sampling, context propagation. À charger quand on met en place du tracing distribué."
4
+ ---
5
+
6
+ # Tracing
7
+
8
+ **Principe premier :** Le tracing n'est pas "du monitoring avec plus de détails" — c'est le seul outil qui te permet de voir une requête traverser 5 services et identifier lequel a pris 90% du temps. Sans tracing, chaque service est une boîte noire. Avec tracing, tu as un diagramme de séquence généré automatiquement. OpenTelemetry est le standard — ne pas utiliser de solution propriétaire.
9
+
10
+ ## Checklist
11
+ - [ ] OpenTelemetry SDK configuré dans chaque service — pas de vendor lock-in
12
+ - [ ] Chaque requête entrante génère un span racine avec trace ID unique
13
+ - [ ] Les appels sortants (HTTP, DB, Redis, queue) créent des spans enfants
14
+ - [ ] Le contexte de trace est propagé automatiquement (W3C Trace Context headers)
15
+ - [ ] Sampling configuré : 100% en dev/staging, sampling adaptatif en prod
16
+ - [ ] Les spans contiennent les attributs clés : service, endpoint, userId, status code
17
+
18
+ ## Anti-patterns
19
+ ### Tracing = logs améliorés
20
+ **Ce qu'on voit :** des spans manuelles `span.setAttribute("message", "processing order")` — comme des logs déguisés.
21
+ **Pourquoi c'est dangereux :** le tracing n'est pas du logging. Son pouvoir vient de l'automatisme : les spans sont créées automatiquement par l'instrumentation, pas manuellement par le dev. Des spans manuelles = du bruit.
22
+ **Faire plutôt :** laisser l'auto-instrumentation créer les spans (HTTP, DB, gRPC). Ajouter manuellement UNIQUEMENT les spans qui représentent des étapes métier importantes (OrderProcessing, PaymentValidation).
23
+
24
+ ### Pas de sampling
25
+ **Ce qu'on voit :** 100% des traces en production. 10 millions de spans/heure. Coût du stockage x10.
26
+ **Pourquoi c'est dangereux :** coût et volume. La plupart des traces normales n'apportent rien. Seules les traces lentes et les traces avec erreurs sont utiles en prod.
27
+ **Faire plutôt :** sampling adaptatif : 100% des traces avec erreur ou > P95. 10% des traces normales. Assez pour voir les patterns, pas assez pour exploser le budget.
28
+
29
+ ## Patterns
30
+ ### OpenTelemetry auto-instrumentation
31
+ **Quand :** tout service en production.
32
+ **Comment :** importer le SDK OTel. Auto-instrumentation pour HTTP, DB, gRPC, queues. Zéro code pour les spans de base. Export vers Jaeger/Tempo/Honeycomb. Standard ouvert — change de backend sans changer le code.
33
+
34
+ ### Span attributes
35
+ **Quand :** chaque span.
36
+ **Comment :** `service.name`, `http.method`, `http.status_code`, `db.system`, `user.id` (pas de PII). Assez pour filtrer et grouper, pas assez pour identifier une personne.