@neikyun/ciel 6.14.0 → 6.14.2

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 (101) hide show
  1. package/assets/.claude/hooks/check-dispatch-gate.sh +14 -41
  2. package/assets/.claude/hooks/memory-engine.py +66 -5
  3. package/assets/.claude/hooks/pre-tool-write.sh +17 -52
  4. package/assets/.claude/hooks/session-start.sh +15 -128
  5. package/assets/.claude/hooks/stop.sh +10 -85
  6. package/assets/.claude/hooks/user-prompt-submit.sh +17 -110
  7. package/assets/.claude/rules/api-design.md +23 -0
  8. package/assets/.claude/rules/backend.md +22 -0
  9. package/assets/.claude/rules/cicd-pipeline.md +23 -0
  10. package/assets/.claude/rules/containers.md +23 -0
  11. package/assets/.claude/rules/database-design.md +22 -0
  12. package/assets/.claude/rules/environments.md +27 -0
  13. package/assets/.claude/rules/frontend.md +25 -0
  14. package/assets/.claude/rules/github.md +22 -0
  15. package/assets/.claude/rules/logging.md +23 -0
  16. package/assets/.claude/rules/monitoring.md +25 -0
  17. package/assets/.claude/rules/research.md +20 -0
  18. package/assets/.claude/settings.json +2 -58
  19. package/assets/.claude/skills/agile/SKILL.md +42 -0
  20. package/assets/.claude/skills/alerting/SKILL.md +55 -0
  21. package/assets/.claude/skills/api-design/SKILL.md +46 -0
  22. package/assets/.claude/skills/appsec/SKILL.md +43 -0
  23. package/assets/.claude/skills/architecture/SKILL.md +74 -0
  24. package/assets/.claude/skills/backend/SKILL.md +41 -0
  25. package/assets/.claude/skills/backup-recovery/SKILL.md +42 -0
  26. package/assets/.claude/skills/caching/SKILL.md +44 -0
  27. package/assets/.claude/skills/cdn/SKILL.md +42 -0
  28. package/assets/.claude/skills/chaos/SKILL.md +41 -0
  29. package/assets/.claude/skills/cicd-pipeline/SKILL.md +56 -0
  30. package/assets/.claude/skills/ciel/SKILL.md +14 -0
  31. package/assets/.claude/skills/ciel/reference.md +171 -0
  32. package/assets/.claude/skills/cloud/SKILL.md +42 -0
  33. package/assets/.claude/skills/code-quality/SKILL.md +42 -0
  34. package/assets/.claude/skills/code-review/SKILL.md +41 -0
  35. package/assets/.claude/skills/communication/SKILL.md +42 -0
  36. package/assets/.claude/skills/containers/SKILL.md +42 -0
  37. package/assets/.claude/skills/cqrs/SKILL.md +41 -0
  38. package/assets/.claude/skills/crypto/SKILL.md +46 -0
  39. package/assets/.claude/skills/data-engineering/SKILL.md +42 -0
  40. package/assets/.claude/skills/database-design/SKILL.md +46 -0
  41. package/assets/.claude/skills/ddd/SKILL.md +45 -0
  42. package/assets/.claude/skills/deployment-strategies/SKILL.md +51 -0
  43. package/assets/.claude/skills/desktop/SKILL.md +42 -0
  44. package/assets/.claude/skills/devsecops/SKILL.md +43 -0
  45. package/assets/.claude/skills/environments/SKILL.md +66 -0
  46. package/assets/.claude/skills/event-driven/SKILL.md +46 -0
  47. package/assets/.claude/skills/frontend/SKILL.md +41 -0
  48. package/assets/.claude/skills/functional/SKILL.md +42 -0
  49. package/assets/.claude/skills/github/SKILL.md +61 -0
  50. package/assets/.claude/skills/high-availability/SKILL.md +42 -0
  51. package/assets/.claude/skills/iac/SKILL.md +46 -0
  52. package/assets/.claude/skills/logging/SKILL.md +46 -0
  53. package/assets/.claude/skills/ml-engineering/SKILL.md +42 -0
  54. package/assets/.claude/skills/mobile/SKILL.md +42 -0
  55. package/assets/.claude/skills/monitoring/SKILL.md +54 -0
  56. package/assets/.claude/skills/networking/SKILL.md +42 -0
  57. package/assets/.claude/skills/nosql/SKILL.md +41 -0
  58. package/assets/.claude/skills/oop-solid/SKILL.md +42 -0
  59. package/assets/.claude/skills/performance/SKILL.md +41 -0
  60. package/assets/.claude/skills/reactive/SKILL.md +42 -0
  61. package/assets/.claude/skills/release-management/SKILL.md +51 -0
  62. package/assets/.claude/skills/research/SKILL.md +69 -0
  63. package/assets/.claude/skills/resilience/SKILL.md +41 -0
  64. package/assets/.claude/skills/serverless/SKILL.md +42 -0
  65. package/assets/.claude/skills/servers/SKILL.md +41 -0
  66. package/assets/.claude/skills/sql/SKILL.md +45 -0
  67. package/assets/.claude/skills/supply-chain/SKILL.md +41 -0
  68. package/assets/.claude/skills/system-design/SKILL.md +91 -0
  69. package/assets/.claude/skills/tech-leadership/SKILL.md +46 -0
  70. package/assets/.claude/skills/testing/SKILL.md +41 -0
  71. package/assets/.claude/skills/tracing/SKILL.md +36 -0
  72. package/assets/CLAUDE.md +31 -122
  73. package/assets/commands/{ciel-memory-bootstrap.md → ciel-memory-init.md} +3 -3
  74. package/assets/commands/ciel-memory.md +210 -0
  75. package/assets/platforms/opencode/.opencode/commands/{ciel-memory-bootstrap.md → ciel-memory-init.md} +3 -3
  76. package/assets/skills/ciel/SKILL.md +8 -97
  77. package/bin/ciel.js +1 -1
  78. package/dist/cli/check.d.ts.map +1 -1
  79. package/dist/cli/check.js +5 -11
  80. package/dist/cli/check.js.map +1 -1
  81. package/dist/cli/claude.d.ts.map +1 -1
  82. package/dist/cli/claude.js +42 -4
  83. package/dist/cli/claude.js.map +1 -1
  84. package/dist/cli/doctor.d.ts +16 -0
  85. package/dist/cli/doctor.d.ts.map +1 -0
  86. package/dist/cli/doctor.js +168 -0
  87. package/dist/cli/doctor.js.map +1 -0
  88. package/dist/cli/index.js +76 -0
  89. package/dist/cli/index.js.map +1 -1
  90. package/dist/cli/init.d.ts.map +1 -1
  91. package/dist/cli/init.js +23 -4
  92. package/dist/cli/init.js.map +1 -1
  93. package/dist/cli/memory.d.ts +18 -0
  94. package/dist/cli/memory.d.ts.map +1 -0
  95. package/dist/cli/memory.js +304 -0
  96. package/dist/cli/memory.js.map +1 -0
  97. package/dist/cli/opencode.js +1 -1
  98. package/dist/cli/opencode.js.map +1 -1
  99. package/package.json +2 -2
  100. /package/assets/{rules → .claude/rules}/security.md +0 -0
  101. /package/assets/{rules → .claude/rules}/testing.md +0 -0
@@ -0,0 +1,171 @@
1
+ # Ciel — Reference
2
+
3
+ Detailed philosophy, full Guards table, and research basis. Loaded on-demand when the orchestrator needs deep context.
4
+
5
+ ---
6
+
7
+ ## Philosophy
8
+
9
+ > *"Understand before generating. Verify before claiming done."*
10
+
11
+ LLMs code by statistical pattern-matching, not reasoning. Ciel forces understanding — framework philosophy, data flow tracing, alternatives consideration, hostile self-critique — before, during, and after code generation.
12
+
13
+ A thinking process — not a mechanical checklist. Apply with judgment. Adapt depth to risk.
14
+
15
+ Named after the Primordial Sage from *Tensei Shitara Slime Datta Ken* — the advisor who reasons at infinite speed before Rimuru acts.
16
+
17
+ ---
18
+
19
+ ## Skill catalog (33 skills)
20
+
21
+ ### Orchestrator (1)
22
+ - `ciel` — this skill, routes to the others
23
+
24
+ ### Workflow (15) — replaces the old monolithic pipeline
25
+
26
+ | Skill | Replaces | Mandatory for |
27
+ |-------|----------|---------------|
28
+ | `depth-classifier` | Depth Gauge table | Ambiguous depth |
29
+ | `quoi-framer` | CRÉER step 1 QUOI | All |
30
+ | `avec-quoi-versioner` | CRÉER step 2 AVEC QUOI | Standard + Critical |
31
+ | `stride-analyzer` | CRÉER step 4 SÉCURITÉ (3 passes) | Critical |
32
+ | `pattern-fitness-check` | CRÉER step 5 CODEBASE fitness | All |
33
+ | `evaluer-sizer` | CRÉER step 6 ÉVALUER | Standard + Critical |
34
+ | `flux-narrator` | CRÉER step 7 FLUX | Standard + Critical |
35
+ | `faire-gatekeeper` | CRÉER step 8 FAIRE gates | All |
36
+ | `security-regression-check` | CRÉER step 8b | Critical |
37
+ | `relire-critic` | CRÉER step 9 RELIRE | All (inline for Trivial, agent for Standard+) |
38
+ | `prouver-verifier` | CRÉER step 10 PROUVER | All |
39
+ | `critiquer-auditor` | Full CRITIQUER 7-step flow | PR/audit reviews |
40
+ | `meta-critiquer` | META-CRITIQUER 30s reflection | All |
41
+
42
+ ### Research (6) — isolated fork via researcher agent
43
+
44
+ | Skill | Purpose |
45
+ |-------|---------|
46
+ | `research-web-sources` | WebFetch official docs + WebSearch best practices |
47
+ | `research-github-issues` | `site:github.com/[lib]/issues` for symptoms |
48
+ | `research-forums` | StackOverflow, Reddit, HN fallback |
49
+ | `validate-source-credibility` | Score sources (official > maintainer > GH > SO > blog) |
50
+ | `synthesize-findings` | Merge outputs into FINDINGS / ANTI-PATTERNS / PHILOSOPHY / API SURFACE / UNCERTAINTIES |
51
+ | `fact-check-claims` | Grep source or fetch docs before asserting |
52
+
53
+ ### Domain (11) — auto-activated by paths glob
54
+
55
+ | Skill | Paths trigger |
56
+ |-------|---------------|
57
+ | `frontend-mastery` | React/Vue/Svelte files |
58
+ | `backend-mastery` | Server framework files |
59
+ | `database-mastery` | `*.sql`, `migrations/**`, `prisma/**` |
60
+ | `security-hardening` | `auth/**`, `security/**`, Token/Password/Secret names |
61
+ | `api-architecture` | `routes/**`, `controllers/**`, `*.proto` |
62
+ | `observability` | logging/metrics/tracing code |
63
+ | `performance-engineering` | Performance-tagged tasks |
64
+ | `refactoring-patterns` | Refactor tasks or duplication ≥ 2 |
65
+ | `ts-js-patterns` | `.ts`, `.tsx`, `.js`, `.jsx` files |
66
+ | `cicd-pipeline-designer` | `.github/workflows/**` |
67
+ | `mcp-configurator` | `.mcp.json`, MCP configuration |
68
+
69
+ ### Meta (5) — self-improvement
70
+
71
+ | Skill | Purpose |
72
+ |-------|---------|
73
+ | `ciel-improve` | Analyze sessions → propose skill rewrites (patch-set for approval) |
74
+ | `skill-creator` | Create new skill from conversation pattern (validated scaffold) |
75
+ | `skill-variant-evaluator` | AutoResearch: generate + eval + compare skill variants |
76
+ | `learnings-capture` | Mine conversation for corrections → append to learnings.md or overlay |
77
+ | `patch-spec` | Shared patch-set format for ciel-improve + skill-freshness-auditor |
78
+
79
+ | Skill | Paths trigger |
80
+ |-------|---------------|
81
+ | `frontend-mastery` | React/Vue/Svelte files |
82
+ | `backend-mastery` | Server framework files |
83
+ | `database-mastery` | `*.sql`, `migrations/**`, `prisma/**` |
84
+ | `security-hardening` | `auth/**`, `security/**`, Token/Password/Secret names |
85
+ | `api-architecture` | `routes/**`, `controllers/**`, `*.proto` |
86
+ | `observability` | logging/metrics/tracing code |
87
+ | `performance-engineering` | Performance-tagged tasks |
88
+ | `refactoring-patterns` | Refactor tasks or duplication ≥ 2 |
89
+
90
+ ### Utility (9)
91
+
92
+ | Skill | Purpose |
93
+ |-------|---------|
94
+ | `commit-writer` | Conventional-format commit messages |
95
+ | `pr-opener` | Open PR with Closes #N, body composition inline |
96
+ | `issue-closer` | Close linked issues with evidence comment |
97
+ | `changelog-updater` | Append versioned entry with fix/revert ratio |
98
+ | `branch-setup` | Create type/N-slug branch from issue |
99
+ | `branch-cleaner` | Delete merged branches safely |
100
+ | `pr-merger` | Merge PRs with branch protection awareness |
101
+ | `release-publisher` | Signed tag + GitHub Release + Sigstore attestations |
102
+ | `issue-creator` | Create GitHub issue with structured body |
103
+
104
+ ### Meta (4) — self-improvement
105
+
106
+ | Skill | Purpose |
107
+ |-------|---------|
108
+ | `ciel-improve` | Analyze sessions → propose skill rewrites (patch-set for approval) |
109
+ | `skill-creator` | Create new skill from conversation pattern (validated scaffold) |
110
+ | `skill-variant-evaluator` | AutoResearch: generate + eval + compare skill variants |
111
+ | `learnings-capture` | Mine conversation for corrections → append to learnings.md or overlay |
112
+
113
+ ---
114
+
115
+ ## Guards — 39 failure modes
116
+
117
+ | Failure mode | How it manifests | Guard |
118
+ |---|---|---|
119
+ | Skipping RECHERCHE | "I already know this" / zero research output | "I already know this" = the red flag. Min: 1 WebSearch + 1 finding |
120
+ | False confidence | "I'm sure this API exists" without evidence | Verify before asserting. No citation = don't know it |
121
+ | Imports missing | Runtime ImportError on first run | API surface: read signatures of every called file before writing |
122
+ | DB columns wrong | Query crashes with "column does not exist" in prod | Verify real schema (migration or `pg_attribute`) before any query |
123
+ | Test URL mismatch | Test passes locally, fails in CI — MSW intercepts wrong host | FLUX test: trace request host:port vs handler host:port |
124
+ | Mock lifecycle error | Mock returns undefined / stale data | FLUX test: when does mock execute — module load or function call? |
125
+ | Pattern copied blindly | Correct syntax, wrong semantics | Fitness check: same problem? same constraints? Any no → adapt |
126
+ | Prior AI pattern | Existing code contradicts official docs | Pattern contradicts docs → DO NOT FOLLOW. Docs > existing code |
127
+ | Degeneration of thought | Self-critique finds 0 issues — same blind spots reinforced | Dispatch critic agent (fresh context) |
128
+ | Context overflow (silent) | Agent report < 200 tokens on Standard task | Re-dispatch with narrower scope. Truncated report = incomplete FAIRE |
129
+ | No alternative | "Obviously the right approach" | Alternatives gate: name X over Y or back to ÉVALUER |
130
+ | Framework bypass | `window.location` in React, `for`+raw SQL, `catch→null`, `as X` cast | Idiomatic gate: justify every bypass signal |
131
+ | Scope drift | "Simple fix" grows to 7 files | Alignment checkpoint at 3+ files: re-read QUOI |
132
+ | Removing without understanding | Removed X → breaks UX nobody tested | Removal gate: Who uses it? What replaces it? What degrades? |
133
+ | Proposing without calculating | "Let's cache all 3826 manga" — fails arithmetic | ÉVALUER sizing: back-of-envelope BEFORE proposing |
134
+ | Debugging wrong layer | 3 CSS fixes when bug was `navigate()` silent fail | 3-layer triage: handler called? simplest action works? only then CSS |
135
+ | Coding without mental model | Code pattern-matches but breaks — data flow not understood | FLUX: narrate full data flow before writing |
136
+ | First draft = final draft | Code works but messy | RELIRE: hostile critic before PROUVER |
137
+ | Fixation after failure | Same fix attempted 3 times, same result | After 2 failures: STOP. List 3 completely different approaches |
138
+ | TDD inversion | Tests written after implementation — pass by definition | Write failing test FIRST (RED) |
139
+ | Coverage theater | 95% coverage, zero meaningful assertions | Does this test verify behavior, or just execute code? |
140
+ | Confirmation bias | Tests only prove it works, never that it fails | Constraint synthesis: write 3 constraints BEFORE checking logs |
141
+ | Over-engineering | Change solves the problem but adds unnecessary complexity | Counterfactual: "What if we do NOTHING?" |
142
+ | Process bloat | SKILL.md grows, steps take longer than the task | Anti-entropy: every addition must simplify OR catch a real failure |
143
+ | Stale overlay | Overlay says React 18, project is React 19 | Per-month: check overlay versions vs real installed |
144
+ | Security fix adds surface | Fix closes vuln A but opens new unguarded endpoint | `security-regression-check`: grep diff for new params, removed auth, new external calls |
145
+ | CI ignored | "Staging works" declared while CI is red | `prouver-verifier` CI gate: `gh run list` must be success |
146
+ | Draft PR left open | CI green but PR stays draft | `meta-critiquer`: CI green + draft → convert to ready |
147
+ | Issue comment missing | Fix deployed but no evidence on the issue | Issue comment gate: add staging PID + AVANT/APRÈS before creating PR |
148
+ | Version changelog missed | Using Ktor 3.x but researching Ktor 2.x docs | RECHERCHE: installed version changelog checked for breaking changes |
149
+ | File re-read | Same file read 3 times in a session | After first read: note pointer. Re-read only if editing |
150
+ | Dead-end loop | Same broken approach attempted in new session | Session progress file: write `.claude/session-progress.md` with failed approaches |
151
+ | Dead code accumulation | Unused imports pile up across sessions | `meta-critiquer` #8: run ruff/knip/Detekt before session end |
152
+ | sleep + tail anti-pattern | `sleep 2 && tail -5 logs/file.log` blocked by harness | Use Monitor for streaming, Bash run_in_background for one-shot waits |
153
+ | Context window pollution | Large agent reports pasted verbatim — context burns fast | Agent result size cap: max 150 lines. Narrow scope if > 300 lines |
154
+ | Dispatch gate bypass | >5 inline Bash/Read/Grep calls without any `Task()` on a Standard+ task | ABORT inline work, emit `Task(subagent_type="ciel-*")` immediately with `[ASSUMED]` markers for any inferred inputs |
155
+ | Hook name drift | Consumer `settings.json` references a hook filename that does not exist in `hooks/` (silent "No such file or directory" on every tool call) | On every hook rename in the repo: grep all published `settings.json` templates and downstream consumer docs for the old name. Version-bump the plugin. |
156
+ | Self-authored rule drift | A rule written in this session (e.g., a new SKILL.md paragraph, a new reference guard) is not reliably followed in subsequent turns; short-term memory decays across tool outputs and compacts. Observed in the v2.4.4→v2.4.7 audit where the `[CIEL N/5]` counter rule was applied exactly once before the agent forgot it. | Mechanical enforcement — hooks, gates, external state files — required for any rule that must hold across >5 turns. Pure SKILL.md text is advisory; without a hook-side counter or settings.json gate, the rule decays within 1-2 turns of its author writing it. v2.5.0 `pre-tool-count.sh` / `post-tool-count.sh` is the canonical example. |
157
+ | Release discipline drift | `feat:`/`fix:` commits accumulate on default branch but VERSION / CHANGELOG / git tag / `gh release` never catch up. Pipeline step 16-17 (`changelog-updater` + `release-publisher`) are opt-in and only triggered on a version-bump PR that no one creates. Observed v2.0 → v2.5.1: 20+ features shipped, zero tags — fixed in the v2.6.0 rattrapage. | Stop-hook `release-gate` (v2.7.0 `hooks/stop.sh`) — when on the default branch AND 3+ conventional `feat:`/`fix:`/`feat!:`/`fix!:` commits exist past the last `git describe --tags --abbrev=0`, prepend a reminder to the meta-critiquer block. Snooze for 60 min: `touch .ciel-release-snooze`. Claude Code only in v2.7.0; OpenCode parity pending `session.idle` `.d.ts` verification. |
158
+
159
+ ---
160
+
161
+ ## Research basis
162
+
163
+ - Audit of 675 commits (62.8% fix/revert with v1.x monolithic skill, 2026-04-04)
164
+ - Anthropic Skills-first paradigm — "Stop building agents, build Skills" (Barry Zhang / Mahesh Murag, AI Engineer Code Summit)
165
+ - [MAR — Multi-Agent Reflexion](https://arxiv.org/html/2512.20845) — degeneration of thought in single-agent critique
166
+ - [SICA — Self-Improving Coding Agent](https://arxiv.org/html/2504.15228v2) — 17→53% improvement via self-edit + metrics
167
+ - [Reflexion](https://arxiv.org/abs/2405.06682) — self-reflection improves problem-solving, p < 0.001
168
+ - CriticBench 2024 — self-critique is the hardest critique mode for LLMs
169
+ - [Process debt research](https://planally.com/why-process-debt-is-the-new-tech-debt/) — monolithic process = friction = skipping
170
+ - OpenHands / JetBrains 2025 — observation masking reduces context burn
171
+ - ACON 2025 — memory pointers reduce token usage 40-60% on file-heavy tasks
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: cloud
3
+ description: "Cloud — IAM least privilege comme principe zero, multi-account, cost optimization, auto-scaling, managed services vs DIY. À charger quand on conçoit une architecture cloud."
4
+ ---
5
+
6
+ # Cloud
7
+
8
+ **Principe premier :** Le cloud n'est pas "des serveurs chez Amazon" — c'est un modèle de responsabilité partagée où la sécurité est programmatique. La console AWS/GCP n'est PAS ton interface de gestion — c'est une porte dérobée pour le debugging. Tout doit être Infrastructure as Code. Le principe zéro est IAM least privilege : chaque service, chaque humain, chaque pipeline a EXACTEMENT les permissions nécessaires et rien de plus. Une permission de trop = une surface d'attaque inutile. Le second principe est que le cloud est un abonnement, pas un achat — chaque ressource qui tourne coûte de l'argent, 24/7.
9
+
10
+ ## Checklist
11
+ - [ ] IAM least privilege : chaque rôle/service a les permissions minimales — revu trimestriellement
12
+ - [ ] Infrastructure as Code (Terraform/Pulumi/CloudFormation) — zéro ressource créée à la main
13
+ - [ ] Environnements séparés (comptes/projects différents) — la dev ne touche pas la prod
14
+ - [ ] Données chiffrées au repos (S3 SSE, RDS encryption, EBS encryption) et en transit (TLS)
15
+ - [ ] Auto-scaling configuré avec min/max et métriques pertinentes
16
+ - [ ] Budget alerts à 80% et 100% + cost anomaly detection
17
+ - [ ] Multi-AZ sur toute charge de production — une AZ peut tomber
18
+
19
+ ## Anti-patterns
20
+ ### IAM AdministratorAccess partout
21
+ **Ce qu'on voit :** chaque service, chaque dev, chaque pipeline a `AdministratorAccess` "pour pas être bloqué". Une clé IAM qui fuit = accès root au compte.
22
+ **Pourquoi c'est dangereux :** IAM n'est pas un obstacle — c'est la SEULE chose qui empêche un attaquant (ou un bug) de supprimer toute ton infrastructure. Un `terraform destroy` accidentel avec des droits admin = tout est perdu. Sans IAM strict, le blast radius d'une fuite de credentials est le compte entier.
23
+ **Faire plutôt :** politiques IAM minimales. `s3:GetObject` sur CE bucket, pas `s3:*`. `ec2:Describe*` pour le monitoring, pas `ec2:TerminateInstances`. Policies gérées en Terraform, pas dans la console. Revue trimestrielle avec IAM Access Analyzer.
24
+
25
+ ### Tout dans le même compte
26
+ **Ce qu'on voit :** dev, staging, prod dans le même compte AWS. Le stagiaire teste un script qui supprime toutes les instances.
27
+ **Pourquoi c'est dangereux :** sans isolation de blast radius, un incident en dev peut détruire la production. Les limites de service (1000 instances, 100 DBs) sont partagées. Les coûts sont mélangés — impossible de savoir ce que coûte la prod vs la dev.
28
+ **Faire plutôt :** comptes séparés par environnement. AWS Organizations ou GCP Folders. Accès cross-account pour les besoins légitimes, jamais l'inverse.
29
+
30
+ ### Facture = surprise de fin de mois
31
+ **Ce qu'on voit :** personne ne regarde les coûts cloud. Un dev lance une instance GPU p3.16xlarge pour tester. Facture x10 à la fin du mois.
32
+ **Pourquoi c'est dangereux :** le cloud facture à l'usage, 24/7. Chaque ressource oubliée coûte. Sans monitoring des coûts, tu découvres les problèmes quand la facture arrive — 30 jours trop tard.
33
+ **Faire plutôt :** budget alerts à 80% et 100%. Tags de coût obligatoires (project, team, environment). Revue mensuelle. Instances non utilisées automatiquement arrêtées (Dev/Staging la nuit, week-end).
34
+
35
+ ## Patterns
36
+ ### IAM least privilege
37
+ **Quand :** toute ressource cloud.
38
+ **Comment :** chaque rôle a `Effect: Allow` uniquement sur les actions et ressources nécessaires. Pas de wildcard `Resource: "*"`. Pas de `Action: "*"`. Utiliser des conditions (IP source, MFA, tags). Partir de zéro et ajouter ce qui est nécessaire, pas l'inverse.
39
+
40
+ ### Multi-AZ
41
+ **Quand :** toute charge de production.
42
+ **Comment :** déployer sur au moins 2 zones de disponibilité. Load balancer répartit. RDS Multi-AZ (standby dans une autre AZ, failover automatique). Si une AZ tombe, le service continue. Coût : ~2× l'infra, mais l'alternative c'est le downtime.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: code-quality
3
+ description: "Code Quality — linting, formatage, analyse statique, dette technique, conventions, complexite cyclomatique. A charger quand on parle de qualite ou standards de code."
4
+ ---
5
+
6
+ # Code Quality
7
+
8
+ **Principe premier :** La qualite du code ne se mesure pas en "proprete" esthetique — elle se mesure en temps de comprehension pour le prochain developpeur. Un code "sale" mais compris en 30 secondes est meilleur qu'un code "propre" qui prend 10 minutes a decoder. Le linter et le formatter existent pour ELIMINER les debats de style, pas pour les multiplier. Si une regle de linting genere des discussions en code review, elle est contre-productive — desactive-la. Le standard de qualite n'est pas la perfection, c'est la consistance : le code doit avoir l'air ecrit par une seule personne, meme si l'equipe a 10 developpeurs.
9
+
10
+ ## Checklist
11
+ - [ ] Le projet a un linter (ESLint, Biome, Ruff, Clippy) avec des regles strictes mais non controversees
12
+ - [ ] Le formatage est automatise (Prettier, dprint, gofmt) — zero debat de style en code review
13
+ - [ ] La complexite cyclomatique est limitee (max 15-20 par fonction) et mesuree dans la CI
14
+ - [ ] Les fichiers sont limits en taille (max 300-500 lignes) — au-dela, splitter
15
+ - [ ] Les commentaires expliquent le POURQUOI, pas le QUOI (le code dit deja QUOI)
16
+ - [ ] Le code mort est supprime, pas commente — git garde l'historique
17
+ - [ ] La duplication est toleree jusqu'a 3 occurrences — abstraire au 4e usage, pas au 2e (Rule of Three)
18
+
19
+ ## Anti-patterns
20
+ ### Linting maximaliste
21
+ **Ce qu'on voit :** 200 regles ESLint activees. `no-console`, `no-param-reassign`, `max-lines-per-function: 20`, `no-else-return`. Chaque commit declenche 15 erreurs qui ne sont PAS des bugs.
22
+ **Pourquoi c'est dangereux :** le linter n'est plus un outil — c'est un obstacle. Les devs le contournent (`eslint-disable` partout), le resultat est pire que pas de linter du tout. La fatigue du linter cree une culture ou les avertissements sont ignores.
23
+ **Faire plutot :** regles qui attrapent des BUGS, pas des preferences : `no-undef`, `no-unused-vars` (erreur, pas warning), `no-unsafe-*`. Formatage automatique, pas manuel. Tout le reste : warning ou off. L'objectif est zero faux positifs, pas un score de linting eleve.
24
+
25
+ ### Refactoring sans filet
26
+ **Ce qu'on voit :** "je refactore cette classe pour la rendre plus propre." 2 semaines plus tard, 40 fichiers modifies, fonctionnalites cassees, aucun test ajoute.
27
+ **Pourquoi c'est dangereux :** le refactoring sans tests n'est pas du refactoring — c'est de la reecriture. Sans filet, chaque changement est un risque. Le "clean code" qui casse la production n'est pas propre — il est dangereux.
28
+ **Faire plutot :** tests AVANT refactoring. Si le code n'a pas de tests, en ecrire (characterization tests). Refactoring en petits pas, commit par commit. Si un test casse, revert immediatement.
29
+
30
+ ### Abstraction prematuree (DRY abuse)
31
+ **Ce qu'on voit :** deux fonctions de 3 lignes qui se ressemblent → abstraction dans une classe mere. La 3e utilisation arrive, difference subtile → `if (specialCase)`. 4e utilisation → 4 parametres de configuration. L'abstraction est devenue plus complexe que le code duplique.
32
+ **Pourquoi c'est dangereux :** le mauvais DRY crée du couplage. Une abstraction prematuree lie ensemble des concepts qui evoluent differemment. Le cout de changer l'abstraction (tous les appels) depasse le cout de la duplication (2-3 endroits).
33
+ **Faire plutot :** Rule of Three : dupliquer jusqu'a 3 fois. A la 3e occurrence, abstraire. L'abstraction a maintenant 3 cas reels pour etre testee. Si la 4e occurrence ne rentre pas, l'abstraction etait prematuree — splitter.
34
+
35
+ ## Patterns
36
+ ### Boy Scout Rule
37
+ **Quand :** maintenance quotidienne.
38
+ **Comment :** "laisse le code plus propre que tu ne l'as trouve." Un petit nettoyage a chaque commit : renommer une variable, extraire une fonction, supprimer du code mort. Pas de refactoring massif — des micro-ameliorations continues.
39
+
40
+ ### Static analysis in CI
41
+ **Quand :** toute PR.
42
+ **Comment :** le linter + l'analyse statique tournent dans la CI. Bloquant sur les regles de securite et de bug. Non-bloquant (annotation dans la PR) pour les suggestions de style. Exemple : `eslint --max-warnings 0` pour les regles d'erreur, `--quiet` pour le reste.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: code-review
3
+ description: "Code Review — PR hygiene, review checklist, constructive feedback, security review, Boy Scout Rule. À charger quand on fait ou reçoit une revue de code."
4
+ ---
5
+
6
+ # Code Review
7
+
8
+ **Principe premier :** La code review n'est pas un gate de qualité — c'est un outil de partage de connaissance. Le but #1 n'est pas de trouver des bugs (les tests et la CI font ça), c'est de s'assurer que le code est compréhensible par quelqu'un qui ne l'a pas écrit. Un bug trouvé en review est un échec des tests. Une incompréhension en review est un échec du code. La métrique n'est pas "nombre de commentaires" mais "est-ce que je pourrais maintenir ce code sans parler à l'auteur ?"
9
+
10
+ ## Checklist
11
+ - [ ] La PR fait < 400 lignes — sinon, découper
12
+ - [ ] Les tests existent, passent, et couvrent les cas limites
13
+ - [ ] La description explique le POURQUOI, pas le QUOI (le diff montre le quoi)
14
+ - [ ] Les noms sont explicites — pas de `x`, `data`, `tmp`, `result`, `handle()`
15
+ - [ ] Pas de code mort, pas de TODO sans ticket, pas de commentaire qui ment
16
+ - [ ] La sécurité est vérifiée : injection, auth, PII exposé
17
+
18
+ ## Anti-patterns
19
+ ### PR de 2000 lignes
20
+ **Ce qu'on voit :** une PR avec 15 fichiers, 3 fonctionnalités, et une description "Refactoring + nouvelle feature + fix bug".
21
+ **Pourquoi c'est dangereux :** impossible à review correctement. Le cerveau humain ne peut pas traiter 2000 lignes de diff. Les bugs passent. La review dure 2h et personne ne la fait sérieusement. Les grosses PRs sont le symptôme d'un découpage du travail mal fait.
22
+ **Faire plutôt :** PR < 400 lignes. Une fonctionnalité, un fix, un refactoring par PR. Petits merges fréquents. Si le changement est gros → feature flag + PRs incrémentales.
23
+
24
+ ### Feedback sur la personne
25
+ **Ce qu'on voit :** "c'est nul", "refais tout", "pourquoi t'as fait comme ça ?" — ton condescendant.
26
+ **Pourquoi c'est dangereux :** ça ne tue pas que l'humeur — ça tue les futures PRs. L'auteur évite de soumettre, ou soumet en cachette. La qualité baisse par peur du feedback. Le coût est à long terme.
27
+ **Faire plutôt :** "Cette approche a le risque X" (pas "tu as mal fait"). Suggestion, pas ordre : "Est-ce qu'on pourrait... ?". Le feedback cible le code, jamais la personne.
28
+
29
+ ### LGTM reflex
30
+ **Ce qu'on voit :** "LGTM" sur une PR de 500 lignes, 2 minutes après l'ouverture.
31
+ **Pourquoi c'est dangereux :** c'est un non-review. Le reviewer n'a pas lu le code. L'auteur n'apprend rien. Les bugs passent. Pire : ça donne une fausse confiance ("c'est reviewé").
32
+ **Faire plutôt :** si tu n'as pas le temps, ne review pas. Si tu review, passe au moins 15 min et trouve au moins UNE chose (positive ou à améliorer). Une review qui ne produit aucun commentaire n'est pas une review.
33
+
34
+ ## Patterns
35
+ ### PR template
36
+ **Quand :** toute PR.
37
+ **Comment :** template concis : contexte, changements, captures/évidence, points d'attention pour le reviewer. L'auteur remplit. Le reviewer a tout le contexte. 2 minutes de remplissage = 15 minutes gagnées en review.
38
+
39
+ ### Boy Scout Rule
40
+ **Quand :** tout fichier touché.
41
+ **Comment :** laisser le code plus propre qu'on ne l'a trouvé. Renommer une variable confuse. Extraire une fonction de 30 lignes. Ajouter un test manquant. Pas de refactoring massif — juste le petit coup de balai.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: communication
3
+ description: "Communication Technique — documentation, diagrammes C4, RFC, post-mortem, presentation, spec writing. A charger quand on communique sur un sujet technique."
4
+ ---
5
+
6
+ # Communication Technique
7
+
8
+ **Principe premier :** La communication technique n'est pas "ecrire ce qu'on sait" — c'est faire comprendre ce que l'autre a besoin de savoir. Le plus grand piege de la communication d'expert : la malediction du savoir. Tu sais tellement bien ton sujet que tu ne peux plus imaginer ce que c'est de ne pas le savoir. Resultat : tu sautes des etapes, utilises du jargon, assumes des prerequis — et ton interlocuteur est perdu. La regle d'or : si tu ne peux pas expliquer ton design a un dev qui vient d'arriver, ton design n'est pas pret. Pas parce que le dev est novice — parce que la clarte est un test de comprehension. Si c'est flou dans ta tete, c'est flou sur le papier.
9
+
10
+ ## Checklist
11
+ - [ ] La documentation est dans le repo, versionnee avec le code — pas dans Confluence/Notion qui se perime
12
+ - [ ] Les decisions techniques sont communiquees avec le POURQUOI (contexte, alternatives) — pas juste la solution
13
+ - [ ] Les diagrammes utilisent un standard reconnu (C4, UML sequence, Mermaid) — pas un outil proprietaire
14
+ - [ ] Les specs sont ecrites avant le code, lues par l'equipe, et amendees — pas "le code est la spec"
15
+ - [ ] Les post-mortems sont blameless : ce qui s'est passe, pourquoi, comment eviter que ca se reproduise
16
+ - [ ] La communication est adaptee au public : C4 level 1 pour stakeholders, level 3 pour devs
17
+ - [ ] Les PR descriptions expliquent le contexte et les trade-offs — pas juste "fixes bug"
18
+
19
+ ## Anti-patterns
20
+ ### Documentation dans un outil separe
21
+ **Ce qu'on voit :** specs dans Confluence, designs dans Notion, decisions dans Trello, code dans GitHub. Rien n'est a jour. Personne ne trouve rien.
22
+ **Pourquoi c'est dangereux :** la documentation eloignee du code est de la documentation morte. Elle n'est pas versionnee avec le code qu'elle decrit. Elle n'est pas revue en PR. Elle pourrit independamment. Le nouveau dev lit la spec Confluence de 2023 et code un feature deja deprecie.
23
+ **Faire plutot :** documentation dans le repo, en markdown, a cote du code qu'elle documente. `docs/architecture.md`, `docs/adrs/`, `services/orders/README.md`. La doc se review en PR comme le code. Si le code change, la doc change dans le meme commit.
24
+
25
+ ### Diagramme = oeuvre d'art
26
+ **Ce qu'on voit :** 3 jours passes a faire un diagramme UML parfait dans un outil proprietaire. Le diagramme est beau. Le code change 2 semaines plus tard. Le diagramme n'est plus a jour et ne peut pas etre modifie (outil perdu, licence expiree).
27
+ **Pourquoi c'est dangereux :** un diagramme est un outil de communication, pas un livrable. Passer 3 jours sur un diagramme qui sera obsolet dans 2 semaines est du gaspillage. L'outil proprietaire cree un barrier a la modification → le diagramme pourrit.
28
+ **Faire plutot :** diagrammes en texte (Mermaid, PlantUML, Graphviz). Versionnes dans le repo. Render automatiquement dans la CI. Assez bons pour communiquer, pas parfaits. Si le diagramme prend plus d'1h, c'est qu'il est trop detaille.
29
+
30
+ ### Post-mortem = blame game
31
+ **Ce qu'on voit :** incident → "qui a deploye ca ?" → recherche de coupable → le dev qui a deploye est blame. Prochaine fois, personne n'osera deployer.
32
+ **Pourquoi c'est dangereux :** chercher un coupable garantit que les incidents futurs seront caches, pas corriges. Les gens ne signalent pas les quasi-incidents. La peur remplace l'apprentissage. L'organisation devient fragile parce qu'elle ne corrige pas ses processus.
33
+ **Faire plutot :** post-mortem blameless. L'incident est cause par le SYSTEME, pas par l'individu. "Qu'est-ce qui dans notre processus a permis cette erreur ?" Action concrete sur le processus pour que ca ne se reproduise pas. L'auteur du deploiement participe au post-mortem sans crainte.
34
+
35
+ ## Patterns
36
+ ### C4 Model
37
+ **Quand :** expliquer l'architecture a differents publics.
38
+ **Comment :** 4 niveaux. Level 1 (Context) : le systeme dans son environnement — pour les stakeholders. Level 2 (Containers) : les briques majeures (app, DB, file system) — pour l'equipe tech elargie. Level 3 (Components) : l'interieur de chaque container — pour les devs. Level 4 (Code) : diagramme de classes — seulement si necessaire. Toujours commencer par le niveau 1, toujours avoir un titre et une legende.
39
+
40
+ ### Spec writing
41
+ **Quand :** feature de > 1 semaine.
42
+ **Comment :** ecrire la spec AVANT de coder. Sections : Problema (quoi et pourquoi), Solution proposee (comment), Alternatives considerees, Impact (migration, cout, risques), Plan de test. Review d'equipe avant implementation. La spec peut etre courte (1-2 pages) — le but est l'alignement, pas la perfection.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: containers
3
+ description: "Containers — multi-stage builds, distroless, non-root, K8s health checks, resource limits, image immutability. À charger quand on travaille avec Docker ou Kubernetes."
4
+ ---
5
+
6
+ # Containers
7
+
8
+ **Principe premier :** Un container n'est pas une VM légère — c'est un process isolé. L'image Docker est un artefact immutable, pas un serveur maintenu à coup de `docker exec`. Chaque couche ajoutée est une surface d'attaque. Le but : l'image la plus petite possible. Et ne jamais tourner en root — non-root est la baseline, pas un bonus.
9
+
10
+ ## Checklist
11
+ - [ ] Multi-stage build : builder (outils) → runtime (artefacts uniquement, minimal)
12
+ - [ ] Image de base minimale : distroless ou Chainguard — pas de shell, pas de package manager
13
+ - [ ] Container non-root (`USER 1001`) — `runAsNonRoot: true` dans K8s
14
+ - [ ] Secrets injectés au runtime (K8s secrets, Vault) — pas dans l'image, pas en ARG
15
+ - [ ] Ressources limitées (CPU/memory limits AND requests) — pas de "illimité"
16
+ - [ ] Health checks : liveness, readiness, startup — les trois
17
+ - [ ] Images taguées par version ET hash de commit — jamais `:latest`
18
+
19
+ ## Anti-patterns
20
+ ### Container en root
21
+ **Ce qu'on voit :** Dockerfile sans `USER`. Le process tourne en root.
22
+ **Pourquoi c'est dangereux :** container compromis = root inside → escalade possible vers l'hôte. La plupart des applications n'ont jamais besoin de root. C'est un défaut historique, pas une nécessité.
23
+ **Faire plutôt :** `USER 1001:1001`. Distroless (pas de shell). `runAsNonRoot: true`, `readOnlyRootFilesystem: true` dans K8s.
24
+
25
+ ### Image obèse
26
+ **Ce qu'on voit :** `FROM node:22` → image de 1.5 Go avec git, curl, npm, code source complet.
27
+ **Pourquoi c'est dangereux :** pull lent = déploiement lent = rollback lent. Surface d'attaque maximale. Coût de stockage.
28
+ **Faire plutôt :** multi-stage : builder compile → runtime minimal. `COPY --from=builder`. Distroless. Image < 100 Mo.
29
+
30
+ ### `:latest` partout
31
+ **Ce qu'on voit :** `image: myapp:latest`. Impossible de savoir quelle version tourne.
32
+ **Pourquoi c'est dangereux :** non-reproductible. Si `latest` change sur le registry, le prochain pod restart aura une version différente. Rollback impossible.
33
+ **Faire plutôt :** tag sémantique + hash de commit. `myapp:v1.2.3`, `myapp:abc1234`. Immutable.
34
+
35
+ ## Patterns
36
+ ### Multi-stage build
37
+ **Quand :** toute image qui compile du code.
38
+ **Comment :** builder (`FROM golang:1.22 AS builder`) → compile → runtime (`FROM gcr.io/distroless/static`) → `COPY --from=builder /app/binary`. Résultat : un binaire et rien d'autre.
39
+
40
+ ### K8s health checks
41
+ **Quand :** tout pod Kubernetes.
42
+ **Comment :** liveness (process vivant ?), readiness (trafic OK ?), startup (init fini ?). Sans readiness, K8s envoie du trafic avant que l'app soit prête → erreurs en boucle.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: cqrs
3
+ description: "CQRS & Event Sourcing — séparation lecture/écriture, projections, event store, eventual consistency. À charger quand les patterns de lecture et d'écriture divergent radicalement."
4
+ ---
5
+
6
+ # CQRS & Event Sourcing
7
+
8
+ **Principe premier :** CQRS n'est pas une architecture — c'est la reconnaissance d'un fait : lire et écrire sont deux opérations fondamentalement différentes. Une écriture doit protéger des invariants, une lecture doit être rapide et façonnée pour le client. Les forcer dans le même modèle crée un compromis qui ne satisfait ni l'un ni l'autre. L'event sourcing est orthogonal : c'est la décision de stocker des événements (faits) plutôt que l'état courant. CQRS + Event Sourcing n'est pas un package deal — tu peux faire du CQRS sans event sourcing.
9
+
10
+ ## Checklist
11
+ - [ ] Le besoin de CQRS est avéré — les lectures et écritures ont VRAIMENT des patterns différents
12
+ - [ ] Le modèle d'écriture protège les invariants (aggregates, validation)
13
+ - [ ] Le modèle de lecture est optimisé pour les requêtes du client (dénormalisé, pré-calculé)
14
+ - [ ] L'eventual consistency est assumée et documentée — pas de "surprise" pour les utilisateurs
15
+ - [ ] Si event sourcing : l'event store est append-only, les projections sont reconstruisibles
16
+ - [ ] Les événements sont versionnés (schema evolution) — un événement de 2024 doit être lisible en 2026
17
+
18
+ ## Anti-patterns
19
+ ### CQRS pour un CRUD
20
+ **Ce qu'on voit :** CQRS + Event Sourcing pour un formulaire de contact. CommandBus, EventStore, Projections, ReadModels — pour stocker un nom et un message.
21
+ **Pourquoi c'est dangereux :** le coût de cette architecture est énorme : eventual consistency, debugging complexe, replay à maintenir. Pour un CRUD, ce coût n'est jamais amorti. Tu passes 10× plus de temps sur l'infrastructure que sur la logique métier.
22
+ **Faire plutôt :** CRUD simple. Repository pattern. Ajouter CQRS UNIQUEMENT quand les lectures sont ≥ 10× plus fréquentes que les écritures ET que les patterns divergent. Même là, commencer par du CQRS sans event sourcing.
23
+
24
+ ### Event sourcing sans besoin d'audit
25
+ **Ce qu'on voit :** tout le système en event sourcing "au cas où on aurait besoin de l'historique". 200 événements par aggregate, replay de 30 secondes au démarrage.
26
+ **Pourquoi c'est dangereux :** l'event sourcing a un coût permanent : snapshots, upcasters, replay, debugging d'event streams. Si le métier n'a pas besoin de l'historique complet des changements (audit, conformité, debug), ce coût est du gaspillage pur.
27
+ **Faire plutôt :** stocker l'état courant. Logger les changements importants dans une table d'audit séparée (pas l'event store). Event sourcing UNIQUEMENT quand l'historique est une exigence métier, pas technique.
28
+
29
+ ### Projections non monitorées
30
+ **Ce qu'on voit :** la projection de lecture est stale (lag de 50 000 événements). Personne ne le sait. Les utilisateurs voient des données vieilles de 10 minutes.
31
+ **Pourquoi c'est dangereux :** l'eventual consistency sans monitoring devient de l'inconsistance tout court. Le lag des projections est la métrique #1 d'un système CQRS — si tu ne la mesures pas, tu ne sais pas dans quel état est ton système.
32
+ **Faire plutôt :** métriques sur le lag des projections. Alerte si lag > N événements ou > M secondes. Read-model reconstruit automatiquement si trop de lag (pas de rattrapage infini).
33
+
34
+ ## Patterns
35
+ ### CQRS sans Event Sourcing
36
+ **Quand :** lectures et écritures divergent mais l'historique n'est pas requis.
37
+ **Comment :** command → validation → DB transactionnelle (état courant). Projection → vue dénormalisée mise à jour dans la même transaction ou via un worker. Pas d'event store, pas de replay. La complexité est proportionnelle au besoin.
38
+
39
+ ### Event Store
40
+ **Quand :** l'historique complet est une exigence métier (finance, audit, conformité).
41
+ **Comment :** append-only. Chaque événement = un fait passé (`OrderPlaced`, pas `PlaceOrder`). Projections = vues dérivables à tout moment. Snapshots réguliers pour éviter le replay complet.
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: crypto
3
+ description: "Cryptographie — principes premiers (confidentialité/intégrité/authenticité), AES-GCM, bcrypt/argon2, TLS, PKI, rotation de clés, non-invention. À charger quand on manipule de la cryptographie."
4
+ ---
5
+
6
+ # Cryptographie
7
+
8
+ **Principe premier :** La cryptographie n'est pas une boîte à outils — c'est la science de transformer des problèmes de confiance en problèmes de gestion de clés. Chaque opération crypto répond à une des trois propriétés fondamentales : confidentialité (chiffrement), intégrité (hash, MAC), ou authenticité (signature). Si tu ne sais pas laquelle des trois tu cherches, tu ne devrais pas écrire de code crypto. Règle d'or : ne jamais inventer un algorithme, ne jamais implémenter un algorithme standard soi-même — utiliser une bibliothèque éprouvée (libsodium, Tink, WebCrypto).
9
+
10
+ ## Checklist
11
+ - [ ] Les mots de passe sont hashés avec argon2id (ou bcrypt cost ≥ 12) — pas de SHA, pas de MD5
12
+ - [ ] Le chiffrement utilise un algorithme authentifié (AES-256-GCM ou ChaCha20-Poly1305) — pas d'AES-ECB, pas de CBC sans HMAC
13
+ - [ ] Les IV/nonces sont générés aléatoirement à chaque chiffrement — jamais réutilisés
14
+ - [ ] Les clés sont stockées dans un KMS/HSM — pas dans le code, pas dans les variables d'environnement
15
+ - [ ] TLS ≥ 1.2 partout, 1.3 si possible — certificats auto-renouvelés
16
+ - [ ] La rotation des clés est automatisée (max 90 jours) et testée
17
+ - [ ] Les algorithmes obsolètes sont bloqués (MD5, SHA1, DES, 3DES, RC4, RSA < 2048)
18
+
19
+ ## Anti-patterns
20
+ ### Chiffrement "maison"
21
+ **Ce qu'on voit :** `function encrypt(text) { return Buffer.from(text).toString('base64'); }`. Ou pire : un algorithme inventé "parce que c'est plus simple".
22
+ **Pourquoi c'est dangereux :** la cryptographie est le seul domaine où "ça marche" ne veut rien dire. Un algorithme cassé produit un output valide. La sécurité ne se teste pas — elle se prouve mathématiquement. Même les experts se font casser — ta solution maison n'a aucune chance.
23
+ **Faire plutôt :** libsodium (recommandé pour toute nouvelle application), Tink (Google), ou le module `crypto` natif avec AES-256-GCM. Ces bibliothèques ont été auditées, attaquées, et corrigées par des cryptographes.
24
+
25
+ ### Clé statique éternelle
26
+ **Ce qu'on voit :** la même clé AES utilisée depuis 3 ans pour chiffrer toutes les données. Pas de rotation, pas de plan de compromission.
27
+ **Pourquoi c'est dangereux :** la rotation limite le rayon de l'explosion. Si une clé fuit et qu'elle chiffre 3 ans de données, TOUT est compromis. Avec une rotation à 90 jours, seules 90 journées sont exposées. La rotation n'est pas pour le cas où la clé est volée — c'est pour QUAND elle est volée.
28
+ **Faire plutôt :** rotation automatique (AWS KMS, Vault, Google Cloud KMS). Les anciennes clés déchiffrent uniquement, ne chiffrent plus. La rotation est un exercice de routine, pas une urgence.
29
+
30
+ ### MD5/SHA1 pour les mots de passe
31
+ **Ce qu'on voit :** `hashed_password = md5(password)` ou `sha1(password + salt)`.
32
+ **Pourquoi c'est dangereux :** MD5 et SHA1 sont conçus pour être RAPIDES — c'est exactement l'inverse de ce qu'on veut pour des mots de passe. Un GPU peut tester des milliards de hashs par seconde. Avec un mot de passe faible, le compte est compromis en secondes.
33
+ **Faire plutôt :** argon2id (vainqueur du Password Hashing Competition, recommandé par l'OWASP). Sinon bcrypt (cost ≥ 12) ou scrypt. Ces algorithmes sont lents ET résistants aux GPU/ASIC. 100ms par hash, c'est imperceptible pour l'utilisateur, dévastateur pour l'attaquant.
34
+
35
+ ## Patterns
36
+ ### AES-256-GCM (chiffrement authentifié)
37
+ **Quand :** chiffrement de données au repos ou en transit.
38
+ **Comment :** GCM fournit confidentialité + intégrité + authenticité en un seul mode. IV aléatoire de 12 bytes (jamais réutilisé avec la même clé). Tag d'authentification de 16 bytes vérifié AVANT de déchiffrer. Pas de padding (contrairement à CBC). L'échec de vérification du tag = données corrompues ou attaquées.
39
+
40
+ ### Argon2id (hash de mot de passe)
41
+ **Quand :** stockage de mots de passe utilisateur.
42
+ **Comment :** mémoire 64MB, itérations 3, parallélisme 4. Résistant aux GPU (mémoire), aux side-channel (data-dependent), et aux ASIC. Le sel est généré aléatoirement et stocké avec le hash. Augmenter les paramètres tous les 2 ans avec la puissance du matériel.
43
+
44
+ ### Rotation de clés automatisée
45
+ **Quand :** toute clé qui chiffre des données en production.
46
+ **Comment :** le KMS génère une nouvelle clé tous les 90 jours. L'ancienne clé passe en "decrypt only". Les nouvelles données sont chiffrées avec la nouvelle clé. Le déchiffrement essaie la clé courante, puis la liste des anciennes. La rotation est non-destructive et réversible.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: data-engineering
3
+ description: "Data Engineering — pipelines ETL/ELT, Spark/Airflow/dbt, data warehouses, streaming vs batch, qualite des donnees. A charger quand on construit des pipelines de donnees."
4
+ ---
5
+
6
+ # Data Engineering
7
+
8
+ **Principe premier :** Le data engineering n'est pas "deplacer des donnees de A a B" — c'est garantir que les bonnes donnees arrivent au bon moment avec la bonne qualite. La donnee est un passif jusqu'a ce qu'elle soit utilisable — un pipeline qui livre des donnees corrompues ou tardives est pire que pas de pipeline du tout (les decisions sont prises sur des donnees fausses). Le vrai defi n'est pas le volume (tout le monde peut scaler) — c'est la qualite, la fraicheur, et la gouvernance. Un pipeline doit etre idempotent (re-run = meme resultat), observable (chaque etape logue ce qu'elle a fait), et testable (tu peux verifier la sortie sans la comparer a elle-meme).
9
+
10
+ ## Checklist
11
+ - [ ] Le pipeline est idempotent : re-run = meme resultat, pas de doublons, pas d'effet cumulatif
12
+ - [ ] Les donnees sont validees a l'ingestion (schema, types, contraintes) — pas de "on verifiera plus tard"
13
+ - [ ] Le lineage est documente (d'ou viennent ces donnees ? quelles transformations ?) — pas de mystere
14
+ - [ ] Les PII sont anonymisees/scrubbees avant d'entrer dans le warehouse (pas dans les requetes)
15
+ - [ ] Les incremental loads utilisent des watermarks fiables (pas `MAX(updated_at)` sur une table sans index)
16
+ - [ ] Le monitoring couvre : fraicheur (age des donnees), volume (trop/pas assez), qualite (% de nulls)
17
+ - [ ] Les backfills sont testees et reversibles — un backfill qui casse la production est un incident
18
+
19
+ ## Anti-patterns
20
+ ### Pipeline fragile aux changements de schema
21
+ **Ce qu'on voit :** le pipeline fait `SELECT *` et insere dans une table cible. La source ajoute une colonne → le pipeline casse. La source supprime une colonne → le pipeline casse.
22
+ **Pourquoi c'est dangereux :** les schemas evoluent, c'est normal. Un pipeline qui casse a chaque changement de schema est un pipeline qui passe plus de temps en panne qu'en production. Chaque panne = donnees manquantes = decisions sur des donnees incompletes.
23
+ **Faire plutot :** definir un contrat de schema (schema registry, Avro, Protobuf). Evolution compatible : ajouter des colonnes optionnelles, jamais supprimer sans migration. Le pipeline lit les colonnes explicitement, pas `SELECT *`. Tests d'evolution de schema dans la CI.
24
+
25
+ ### "On nettoiera les donnees plus tard"
26
+ **Ce qu'on voit :** ingestion brute de tout. "On fera la qualite dans le data warehouse." 6 mois plus tard : 500 To de donnees, 40% de valeurs nulles, colonnes inutilisables.
27
+ **Pourquoi c'est dangereux :** la qualite des donnees se degrade avec le temps — chaque transformation ajoute une couche d'interpretation. Plus tu attends pour nettoyer, plus c'est dur et cher. Le data warehouse devient un data swamp.
28
+ **Faire plutot :** validation a l'ingestion (schema, types, contraintes metier). Rejeter les donnees invalides dans une dead letter queue, pas dans le warehouse. Les donnees propres sont plus petites, plus rapides, plus utiles.
29
+
30
+ ### Pipeline = boite noire
31
+ **Ce qu'on voit :** le pipeline tourne dans Airflow/Dagster. Pas de logs structures. "Le DAG a echoue" — aucun diagnostic possible sans regarder le code.
32
+ **Pourquoi c'est dangereux :** sans observabilite, chaque echec est une enquete policiere. Les pipelines sont des programmes distribues — ils echouent pour 50 raisons differentes. Sans logs structures (combien de rows traitees, combien de temps par etape, quelles valeurs aberrantes), le MTTR est de l'ordre de l'heure.
33
+ **Faire plutot :** chaque etape logue : nombre de records traites, duree, nombre d'erreurs/valides, watermark utilise. Dashboards de sante par pipeline. Alertes sur deviation (moins de donnees que d'habitude = probleme upstream).
34
+
35
+ ## Patterns
36
+ ### Medaillon architecture (Bronze/Silver/Gold)
37
+ **Quand :** data lake ou data warehouse avec plusieurs consommateurs.
38
+ **Comment :** Bronze = donnees brutes (ingestion, append-only, schema preserve). Silver = donnees nettoyees, deduplicatees, jointes. Gold = donnees metier agreggees, pretes pour la consommation. Chaque couche a un proprietaire et un SLA de fraicheur.
39
+
40
+ ### Watermark incremental
41
+ **Quand :** pipeline qui traite des donnees par lots incrementaux.
42
+ **Comment :** utiliser une colonne de watermark monotone (`updated_at`, `event_time`, `sequence_id`). Stocker le watermark precedent. Charger `WHERE updated_at > last_watermark`. Gerer les late arrivals avec une fenetre de tolerance (ex: recharger les 2 dernieres heures en plus du delta).
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: database-design
3
+ description: "Database Design — le schema comme contrat, normalisation, indexation, migrations sans downtime, UUID vs bigint. À charger quand on crée ou modifie un schéma de base de données."
4
+ ---
5
+
6
+ # Database Design
7
+
8
+ **Principe premier :** Le schéma de base de données est le contrat le plus coûteux à modifier dans une application. Changer du code = redéployer (minutes). Changer un schéma avec 50M rows = migration potentiellement bloquante (heures ou jours). Le design de schéma est donc un exercice d'anticipation : tout ce qui est facile à changer plus tard peut être décidé plus tard ; tout ce qui est dur à changer doit être décidé maintenant. La normalisation n'est pas un dogme — c'est un défaut qui minimise la redondance. Dénormaliser doit être un choix explicite, pas un accident.
9
+
10
+ ## Checklist
11
+ - [ ] Le schéma est en 3NF sauf raison explicite de dénormaliser (documentée)
12
+ - [ ] Chaque table a une primary key — UUID v7 si distribué, bigint si centralisé
13
+ - [ ] Les foreign keys sont définies ET indexées (intégrité + performance)
14
+ - [ ] Les colonnes sont NOT NULL par défaut — nullable est l'exception, justifiée
15
+ - [ ] Les migrations sont réversibles (up + down) et testées en rollback dans la CI
16
+ - [ ] Les migrations sur grosses tables (> 1M rows) utilisent une stratégie sans lock (expand/contract ou gh-ost)
17
+ - [ ] Pas de logique métier dans la DB — triggers et stored procedures = application
18
+
19
+ ## Anti-patterns
20
+ ### JSON pour tout
21
+ **Ce qu'on voit :** `data JSONB NOT NULL` — nom, email, adresse, commandes, tout dans une colonne JSON. "C'est flexible".
22
+ **Pourquoi c'est dangereux :** pas de typage, pas de contrainte, pas d'index utilisable. "Flexible" veut dire "le contrat n'existe pas". Impossible de faire un rapport sans parser toute la table. La DB devient un dump de documents sans structure.
23
+ **Faire plutôt :** colonnes typées pour tout champ connu et requêté. JSONB réservé aux données vraiment variables (metadata, preferences, config). La structure est le produit — ne pas y renoncer pour de la flexibilité.
24
+
25
+ ### Migration = ALTER TABLE direct
26
+ **Ce qu'on voit :** `ALTER TABLE orders ADD COLUMN status VARCHAR NOT NULL DEFAULT 'pending'` lancé sur une table de 10M rows à 14h en production.
27
+ **Pourquoi c'est dangereux :** PostgreSQL locke la table entière pendant l'ALTER. Pour 10M rows, ça peut prendre 20 minutes. Tout le service est down — commandes, paiements, expéditions. La migration en une étape est la cause #1 des outages de DB.
28
+ **Faire plutôt :** expand/contract en 3 étapes : (1) ADD COLUMN sans NOT NULL (instantané), (2) remplir par batches de 1000 rows avec des pauses, (3) ajouter NOT NULL après que toutes les rows ont une valeur. Chaque étape est une migration séparée, déployable et rollbackable indépendamment.
29
+
30
+ ### Index manquant sur FK
31
+ **Ce qu'on voit :** `order_items.order_id REFERENCES orders(id)` sans index sur `order_id`. Un DELETE sur orders déclenche un seq scan de order_items.
32
+ **Pourquoi c'est dangereux :** chaque DELETE/UPDATE cascadé parcourt toute la table enfant. Sur 10M de order_items, un DELETE d'une commande prend 30 secondes au lieu de 1ms. Deadlocks en cascade.
33
+ **Faire plutôt :** règle mécanique : toute foreign key a un index. C'est vérifiable automatiquement (pghero, linter SQL). Pas d'exception.
34
+
35
+ ## Patterns
36
+ ### Expand/Contract (migration sans downtime)
37
+ **Quand :** toute modification de schéma sur une table > 100K rows en production.
38
+ **Comment :** Phase expand : ajouter (colonnes, tables) sans rien supprimer — l'ancien code continue de fonctionner. Phase migrate : backfill par batches. Phase contract : supprimer l'ancien après validation que tout le nouveau code est déployé. Minimum 2 PRs séparées.
39
+
40
+ ### UUID v7 pour PK distribuée
41
+ **Quand :** besoin d'IDs uniques sans séquence centrale, triables chronologiquement.
42
+ **Comment :** UUID v7 = timestamp (48 bits) + random (74 bits). Chronologiquement triable (contrairement à UUID v4), pas de fragmentation d'index B-tree. Généré côté application, pas de round-trip DB pour l'ID.
43
+
44
+ ### Index partiel
45
+ **Quand :** une requête filtre sur une condition qui ne concerne qu'une petite fraction des rows.
46
+ **Comment :** `CREATE INDEX idx_active ON orders (created_at) WHERE status = 'active'`. L'index est plus petit, plus rapide à scanner, plus rapide à mettre à jour. Ne pas indexer ce qui n'est jamais cherché.