@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.
- package/assets/.claude/hooks/check-dispatch-gate.sh +14 -41
- package/assets/.claude/hooks/memory-engine.py +66 -5
- package/assets/.claude/hooks/pre-tool-write.sh +17 -52
- package/assets/.claude/hooks/session-start.sh +15 -128
- package/assets/.claude/hooks/stop.sh +10 -85
- package/assets/.claude/hooks/user-prompt-submit.sh +17 -110
- package/assets/.claude/rules/api-design.md +23 -0
- package/assets/.claude/rules/backend.md +22 -0
- package/assets/.claude/rules/cicd-pipeline.md +23 -0
- package/assets/.claude/rules/containers.md +23 -0
- package/assets/.claude/rules/database-design.md +22 -0
- package/assets/.claude/rules/environments.md +27 -0
- package/assets/.claude/rules/frontend.md +25 -0
- package/assets/.claude/rules/github.md +22 -0
- package/assets/.claude/rules/logging.md +23 -0
- package/assets/.claude/rules/monitoring.md +25 -0
- package/assets/.claude/rules/research.md +20 -0
- package/assets/.claude/settings.json +2 -58
- package/assets/.claude/skills/agile/SKILL.md +42 -0
- package/assets/.claude/skills/alerting/SKILL.md +55 -0
- package/assets/.claude/skills/api-design/SKILL.md +46 -0
- package/assets/.claude/skills/appsec/SKILL.md +43 -0
- package/assets/.claude/skills/architecture/SKILL.md +74 -0
- package/assets/.claude/skills/backend/SKILL.md +41 -0
- package/assets/.claude/skills/backup-recovery/SKILL.md +42 -0
- package/assets/.claude/skills/caching/SKILL.md +44 -0
- package/assets/.claude/skills/cdn/SKILL.md +42 -0
- package/assets/.claude/skills/chaos/SKILL.md +41 -0
- package/assets/.claude/skills/cicd-pipeline/SKILL.md +56 -0
- package/assets/.claude/skills/ciel/SKILL.md +14 -0
- package/assets/.claude/skills/ciel/reference.md +171 -0
- package/assets/.claude/skills/cloud/SKILL.md +42 -0
- package/assets/.claude/skills/code-quality/SKILL.md +42 -0
- package/assets/.claude/skills/code-review/SKILL.md +41 -0
- package/assets/.claude/skills/communication/SKILL.md +42 -0
- package/assets/.claude/skills/containers/SKILL.md +42 -0
- package/assets/.claude/skills/cqrs/SKILL.md +41 -0
- package/assets/.claude/skills/crypto/SKILL.md +46 -0
- package/assets/.claude/skills/data-engineering/SKILL.md +42 -0
- package/assets/.claude/skills/database-design/SKILL.md +46 -0
- package/assets/.claude/skills/ddd/SKILL.md +45 -0
- package/assets/.claude/skills/deployment-strategies/SKILL.md +51 -0
- package/assets/.claude/skills/desktop/SKILL.md +42 -0
- package/assets/.claude/skills/devsecops/SKILL.md +43 -0
- package/assets/.claude/skills/environments/SKILL.md +66 -0
- package/assets/.claude/skills/event-driven/SKILL.md +46 -0
- package/assets/.claude/skills/frontend/SKILL.md +41 -0
- package/assets/.claude/skills/functional/SKILL.md +42 -0
- package/assets/.claude/skills/github/SKILL.md +61 -0
- package/assets/.claude/skills/high-availability/SKILL.md +42 -0
- package/assets/.claude/skills/iac/SKILL.md +46 -0
- package/assets/.claude/skills/logging/SKILL.md +46 -0
- package/assets/.claude/skills/ml-engineering/SKILL.md +42 -0
- package/assets/.claude/skills/mobile/SKILL.md +42 -0
- package/assets/.claude/skills/monitoring/SKILL.md +54 -0
- package/assets/.claude/skills/networking/SKILL.md +42 -0
- package/assets/.claude/skills/nosql/SKILL.md +41 -0
- package/assets/.claude/skills/oop-solid/SKILL.md +42 -0
- package/assets/.claude/skills/performance/SKILL.md +41 -0
- package/assets/.claude/skills/reactive/SKILL.md +42 -0
- package/assets/.claude/skills/release-management/SKILL.md +51 -0
- package/assets/.claude/skills/research/SKILL.md +69 -0
- package/assets/.claude/skills/resilience/SKILL.md +41 -0
- package/assets/.claude/skills/serverless/SKILL.md +42 -0
- package/assets/.claude/skills/servers/SKILL.md +41 -0
- package/assets/.claude/skills/sql/SKILL.md +45 -0
- package/assets/.claude/skills/supply-chain/SKILL.md +41 -0
- package/assets/.claude/skills/system-design/SKILL.md +91 -0
- package/assets/.claude/skills/tech-leadership/SKILL.md +46 -0
- package/assets/.claude/skills/testing/SKILL.md +41 -0
- package/assets/.claude/skills/tracing/SKILL.md +36 -0
- package/assets/CLAUDE.md +31 -122
- package/assets/commands/{ciel-memory-bootstrap.md → ciel-memory-init.md} +3 -3
- package/assets/commands/ciel-memory.md +210 -0
- package/assets/platforms/opencode/.opencode/commands/{ciel-memory-bootstrap.md → ciel-memory-init.md} +3 -3
- package/assets/skills/ciel/SKILL.md +8 -97
- package/bin/ciel.js +1 -1
- package/dist/cli/check.d.ts.map +1 -1
- package/dist/cli/check.js +5 -11
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/claude.d.ts.map +1 -1
- package/dist/cli/claude.js +42 -4
- package/dist/cli/claude.js.map +1 -1
- package/dist/cli/doctor.d.ts +16 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +168 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.js +76 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +23 -4
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/memory.d.ts +18 -0
- package/dist/cli/memory.d.ts.map +1 -0
- package/dist/cli/memory.js +304 -0
- package/dist/cli/memory.js.map +1 -0
- package/dist/cli/opencode.js +1 -1
- package/dist/cli/opencode.js.map +1 -1
- package/package.json +2 -2
- /package/assets/{rules → .claude/rules}/security.md +0 -0
- /package/assets/{rules → .claude/rules}/testing.md +0 -0
|
@@ -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.
|
package/assets/CLAUDE.md
CHANGED
|
@@ -1,128 +1,37 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Ciel v9
|
|
2
2
|
|
|
3
|
-
**Core
|
|
3
|
+
**Core:** Understand before generating. Verify before claiming done.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Regles dures (4)
|
|
6
|
+
1. Test d'abord — RED (test echoue) → GREEN (passe) → REFACTOR. Jamais de code sans test.
|
|
7
|
+
2. Zero secret — pas de cle, token, ou mot de passe dans le code. Variables d'environnement uniquement.
|
|
8
|
+
3. Pas de placeholder — pas de `// TODO`, pas de `// ...rest of code`. Tout code est complet ou absent.
|
|
9
|
+
4. Pas de "no error in logs" = preuve — declenche le scenario, vois un signal positif.
|
|
6
10
|
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
5. **Pipeline complet** — 18 etapes dans l'ordre. Ne saute jamais TESTER, RELIRE, ni PROUVER.
|
|
14
|
-
6. **Pipeline invisible** — jamais de tableaux d'etapes, de "DOCS termine", de "Passons a QUOI", ni de comptes-rendus META dans la sortie visible. L'utilisateur voit les resultats, jamais la machinerie.
|
|
15
|
-
7. **Skills obligatoires** — a chaque etape du pipeline, charger le skill workflow correspondant avec l'outil `Skill` (colonne "Skill a charger" dans le tableau). Ne jamais sauter un skill: son contenu n'est pas dans ta memoire d'entrainement, il est dans le fichier SKILL.md.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Pipeline (18 etapes — a tracker en interne, jamais affiche)
|
|
20
|
-
|
|
21
|
-
Chaque etape a un skill workflow dedie a charger via `Skill` avant de l'executer.
|
|
22
|
-
|
|
23
|
-
| Step | Depth | Skill a charger | Action |
|
|
24
|
-
|------|-------|-----------------|--------|
|
|
25
|
-
| **DOCS** | All | `depth-classifier` | Lire AGENTS.md, CLAUDE.md, ciel-overlay.md, .ciel/map.json. Classifier la profondeur et ecrire le resultat (Trivial/Standard/Critical) dans `.ciel/last-depth`. Charger les skills domaine pertinents via `Skill`. |
|
|
26
|
-
| **QUOI** | All | `quoi-framer` | Objectif (1 phrase) + NOT-X + Definition of Done |
|
|
27
|
-
| **ASK** | Std/Crit | `ask-window` | `AskUserQuestion` si ambigu. Sinon DECIDE. |
|
|
28
|
-
| **AVEC QUOI** | Std/Crit | `avec-quoi-versioner` | Lire les versions installees (package.json) — pas la memoire |
|
|
29
|
-
| **DIVERGE** | Std/Crit | `diverge` | 2-3 approches differentes AVANT de choisir |
|
|
30
|
-
| **RECHERCHE** | Std/Crit | — | Dispatch `ciel-researcher` avec les skills domaine: docs officielles + anti-patterns + changelog |
|
|
31
|
-
| **SECURITE** | Critical | `stride-analyzer` | STRIDE 6 categories → `ciel-critic` MODE=CRITIQUER |
|
|
32
|
-
| **CODEBASE** | Std/Crit | — | Dispatch `ciel-explorer` avec les skills domaine: pattern fitness + data flow + git history |
|
|
33
|
-
| **EVALUER** | Std/Crit | `evaluer-sizer` | Sizing + 2 modes d'echec + contrefactuel |
|
|
34
|
-
| **ASK2** | Std/Crit | — | Valider le plan avec l'utilisateur avant de coder |
|
|
35
|
-
| **FAIRE** | All | `faire-gatekeeper` | 6 gates: test-first RED, alternatives, idiomatique, qualite, removal safety, boy-scout |
|
|
36
|
-
| **TESTER** | Std/Crit | — | Executer la suite de tests. RED? → FAIRE. GREEN? → continuer. Max 3 boucles. Commande: .ciel/map.json → package.json → Makefile |
|
|
37
|
-
| **ADR** | Decision | `adr-auto` | Si decision architecturale → `docs/adrs/` |
|
|
38
|
-
| **RELIRE** | Std/Crit | `relire-critic` | Dispatch `ciel-critic` MODE=RELIRE: 4 RISQUES + FIX/ACCEPT/DEFER |
|
|
39
|
-
| **PROUVER** | Std/Crit | `prouver-verifier` | Evidence AVANT/APRES + CI gate + issue comment gate |
|
|
40
|
-
| **MEMOIRE** | All | `memoire` | Capturer bugs decouverts, patterns appris, decisions utilisateur, anti-patterns detectes → `python3 .claude/hooks/memory-engine.py capture` |
|
|
41
|
-
| **COMPILER** | Std/Crit | `savoir-compiler` | Si >= 5 episodes non compiles → compiler en `.ciel/wiki/`. Sinon skip. |
|
|
42
|
-
| **META** | All | `meta-critiquer` | Reflection (10 items ci-dessous). Jamais dans la sortie visible. |
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## Depth Gauge
|
|
47
|
-
|
|
48
|
-
| Level | Example | Pipeline |
|
|
49
|
-
|-------|---------|----------|
|
|
50
|
-
| **Trivial** | rename, typo, 1-liner | DOCS → QUOI → FAIRE → META |
|
|
51
|
-
| **Standard** | hook, route, component, service | 18 etapes completes |
|
|
52
|
-
| **Critical** | auth, DB schema, security, payment | 18 + STRIDE + `ciel-critic` obligatoire |
|
|
53
|
-
| **Spike** | POC, draft, experimental | QUOI → ASK → AVEC QUOI → DIVERGE → FAIRE (relaxe) → META |
|
|
11
|
+
## Depth (le systeme adapte la rigueur automatiquement)
|
|
12
|
+
| Niveau | Declencheur | Comportement |
|
|
13
|
+
|--------|-------------|--------------|
|
|
14
|
+
| **Trivial** | rename, typo, 1-liner | Pas de dispatch |
|
|
15
|
+
| **Standard** | tout le reste | Dispatch researcher+explorer avant d'ecrire |
|
|
16
|
+
| **Critical** | auth, DB, securite, payment | Idem + STRIDE + critic obligatoire |
|
|
54
17
|
|
|
55
18
|
Doute → Standard. Touche aux donnees utilisateur ou auth → Critical.
|
|
56
19
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Top 11 Guards
|
|
79
|
-
|
|
80
|
-
1. **"I already know this" = red flag** → RESEARCH. Fais-le.
|
|
81
|
-
2. **Pas de citation = tu ne sais pas** → verifie avant d'affirmer.
|
|
82
|
-
3. **Colonnes DB** → verifier le vrai schema avant de query (fichier migration, pas memoire).
|
|
83
|
-
4. **Pattern copie aveuglement** → fitness check echoue. Verifie avant de copier.
|
|
84
|
-
5. **Auto-critique dans le meme contexte** = memes angles morts → dispatch `ciel-critic`.
|
|
85
|
-
6. **Aucune alternative consideree** → retour a EVALUER. Trouve 2-3 approches.
|
|
86
|
-
7. **Scope drift a 3+ fichiers** → relire QUOI. Recentre-toi.
|
|
87
|
-
8. **Test d'abord (RED)**, jamais apres. Toujours.
|
|
88
|
-
9. **"No error in logs" ≠ preuve** → declenche le scenario, vois un signal positif.
|
|
89
|
-
10. **Test suite doit passer** — execute la commande de test apres FAIRE. RED → corrige → re-run. Max 3 boucles puis escalade.
|
|
90
|
-
11. **Episodes sans compilation = savoir dormant** — >= 5 episodes non compiles → declencher `savoir-compiler`. La memoire qui n'est jamais distillee est de la memoire perdue.
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## Cued-recall memory
|
|
95
|
-
|
|
96
|
-
Ecrire dans `.ciel/memory/episodes/` via `memory-engine.py capture`. Ne jamais ecrire dans le Claude Code auto-memory (`MEMORY.md`). Confirmer avec `AskUserQuestion` avant chaque capture.
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## META — 10 items de reflexion (interne, jamais visible)
|
|
101
|
-
|
|
102
|
-
A la fin de chaque tache, charger `meta-critiquer` et repondre a ces 10 questions DANS LE THINKING:
|
|
103
|
-
|
|
104
|
-
1. Depth match — la classification etait-elle correcte ? Sinon, quel indice a ete manque ?
|
|
105
|
-
2. Pipeline — etape sautee ou baclee ? Laquelle ?
|
|
106
|
-
3. Skill manquant — un skill domaine aurait-il du etre charge et ne l'a pas ete ?
|
|
107
|
-
4. Subagent — un dispatch a-t-il ete oublie ? (researcher/explorer en parallele)
|
|
108
|
-
5. RELIRE — le critique a-t-il trouve quelque chose que je n'avais pas vu ?
|
|
109
|
-
6. PROUVER — l'evidence est-elle concrete (log/curl/screenshot) ou juste "no error" ?
|
|
110
|
-
7. MEMOIRE — y a-t-il une intervention, decision, ou decouverte a capturer ?
|
|
111
|
-
8. Contrefactuel — qu'aurais-je fait differemment avec 2x plus de temps ?
|
|
112
|
-
9. Angle mort — qu'ai-je omis que l'utilisateur va probablement me demander ensuite ?
|
|
113
|
-
10. Lecon — 1 phrase a memoriser pour la prochaine tache similaire
|
|
114
|
-
|
|
115
|
-
---
|
|
116
|
-
|
|
117
|
-
## Echecs frequents
|
|
118
|
-
|
|
119
|
-
- **Pas de DOCS** → toujours lire `.ciel/map.json` + `ciel-overlay.md` en premier
|
|
120
|
-
- **Pas de QUOI** → definir objectif + NOT-X + DoD avant de toucher au code
|
|
121
|
-
- **Pas de DIVERGE** → generer 2-3 alternatives avant d'en choisir une
|
|
122
|
-
- **Pas de subagents** → dispatcher researcher + explorer en parallele avant tout Edit/Write
|
|
123
|
-
- **Pas de RELIRE** → toujours dispatcher `ciel-critic` MODE=RELIRE avant merge
|
|
124
|
-
- **Pas de PROUVER** → montrer evidence AVANT/APRES (logs, curl, screenshot)
|
|
125
|
-
- **Pas de MEMOIRE** → sauver `.ciel/map.json` et capturer a `.ciel/memory/` en fin de tache
|
|
126
|
-
- **Pas de META** → toujours executer la reflection (10 items)
|
|
127
|
-
- **Pas de COMPILER** → si >= 5 episodes non compiles, declencher `savoir-compiler`
|
|
128
|
-
- **Pipeline visible** → le pipeline est dans le thinking UNIQUEMENT
|
|
20
|
+
## Subagents (dispatch en parallele avant tout Write)
|
|
21
|
+
| Agent | Quand | Contrat |
|
|
22
|
+
|-------|-------|---------|
|
|
23
|
+
| `ciel-researcher` | Avant d'ecrire | Docs officielles, anti-patterns, versions, changelogs |
|
|
24
|
+
| `ciel-explorer` | En parallele avec researcher | Codebase patterns, data flow, git history |
|
|
25
|
+
| `ciel-critic` | Apres le code, avant le commit | 4 risques + FIX/ACCEPT/DEFER |
|
|
26
|
+
| `ciel-improver` | Uniquement /ciel-improve, /ciel-eval | Analyse + propositions |
|
|
27
|
+
|
|
28
|
+
## Skills (~50 skills domaine, invocables via Skill())
|
|
29
|
+
- **Avant d'ecrire du code**, evalue le contexte et invoque tous les skills pertinents avec `Skill()`. Une tache touche souvent plusieurs domaines (DB + langage + testing...). L'IA est assez intelligente pour matcher sans table de keywords.
|
|
30
|
+
- Les skills NE s'auto-chargent PAS. Tu dois les invoquer explicitement.
|
|
31
|
+
- **Rules** (`.claude/rules/*.md`) — elles, s'auto-chargent via `paths:`. Mecanisme separe.
|
|
32
|
+
|
|
33
|
+
## META (thinking uniquement, jamais visible)
|
|
34
|
+
1. Qu'ai-je manque que l'utilisateur va me demander ensuite ?
|
|
35
|
+
2. Quelle decision ou decouverte merite d'etre sauvegardee en memoire ?
|
|
36
|
+
3. Si je devais refaire cette tache, que ferais-je differemment ?
|
|
37
|
+
test
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
description: Scan project for ingestable tribal docs (lessons.md, ciel-overlay.md, .claude/rules/, Claude Code auto-memory at ~/.claude/projects/<slug>/memory/, etc.) and propose ingestion into the cued-recall memory under .ciel/memory/. Reports findings if no sources found. Always confirms each candidate with the user before writing.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
# /ciel-memory-
|
|
5
|
+
# /ciel-memory-init — Initialize Cued-Recall Memory
|
|
6
6
|
|
|
7
7
|
**Purpose:** First-run scan of an existing project to convert tribal knowledge already documented in `lessons.md`, `ciel-overlay.md`, `.claude/rules/`, Claude Code's per-project auto-memory (`~/.claude/projects/<slug>/memory/`), and similar files into the structured cued-recall memory at `.ciel/memory/`.
|
|
8
8
|
|
|
9
|
-
**Usage:** `/ciel-memory-
|
|
9
|
+
**Usage:** `/ciel-memory-init` (no args)
|
|
10
10
|
|
|
11
11
|
This is **deterministic**: no agent dispatch, no pipeline, no DIVERGE/EVALUER. Just scan, propose, write on user confirmation.
|
|
12
12
|
|
|
@@ -163,7 +163,7 @@ Report:
|
|
|
163
163
|
- N memories captured
|
|
164
164
|
- Sources processed
|
|
165
165
|
- Index rebuilt with M total entries
|
|
166
|
-
- Suggest: "Cued-recall memory now active. Memories will auto-inject when their cues match in future tasks. Run `/ciel-memory-
|
|
166
|
+
- Suggest: "Cued-recall memory now active. Memories will auto-inject when their cues match in future tasks. Run `/ciel-memory-init` again anytime to re-scan for new tribal docs."
|
|
167
167
|
|
|
168
168
|
---
|
|
169
169
|
|