J'ai toujours eu un esprit innovant et une volonté naturelle de me tourner vers les sujets techniques. Ce site est mon laboratoire, un bac à sable où je teste des technos et des hypothèses en tant que builder.
Je l'utilise pour explorer l'IA, développer mes compétences de builder et valider des patterns en conditions réelles. Avec passion et curiosité. Chaque feature ici est une vraie expérience : une architecture qu'on pousse pour voir jusqu'où elle tient, un pipeline qu'on conçoit pour comprendre ses limites, un pattern qu'on découvre en le construisant. Ce n'est pas un portfolio de présentation. C'est un système vivant.
pm-toolkit.html qui les enchaîne, et product-brief.html qui synthétise la session en un livrable exportable (PDF, Markdown, ou export one-click vers Notion en OAuth). Deux modules partagés sans dépendances : pm-core.js centralise les appels au proxy, le parsing JSON tolérant et les erreurs ; pm-session.js persiste les sorties par projet dans localStorage (sessions multi-projets) et en dérive un contexte canonique que chaque outil aval consomme, pas seulement le suivant.ctx.waitUntil, zéro impact sur les temps de réponse. Plan gratuit Langfuse Cloud : 50 000 observations/mois.wrangler.toml. Le handler scheduled() du Worker exécute la même logique que POST /veille-refresh : fetch des 13 flux RSS, synthèse de chaque catégorie via Groq, puis archivage en KV par semaine ISO, ce qui fait grossir l'historique tout seul. Aucune dépendance externe, aucun secret à transmettre (le cron tourne dans le Worker), toute l'orchestration vit dans le repo versionné.pm-session.js : chaque outil sauvegarde ses sorties structurées dans localStorage sous une clé commune, qui en dérive un contexte canonique partagé, pré-rempli automatiquement dans les champs de chaque outil aval (pas seulement le suivant) et récapitulé dans un panneau Contexte PM. Zéro backend, zéro compte, zéro friction.pm-toolkit.html centralise l'entrée, rend la séquence lisible, et pm-session.js dérive un contexte canonique partagé : chaque sortie (persona, hypothèses, pain points, opportunités, OKR, priorités, stories) est normalisée dans un vocabulaire commun où chaque outil aval pioche tout le savoir amont, pas seulement le précédent, via localStorage, sans backend, sans compte, sans friction.localStorage ou les logs. À la place, le flux est entièrement côté Worker : pm-export.js construit les blocs Notion depuis la session puis appelle POST /export/prepare, qui stocke transitoirement le payload en KV (TTL 10 min) et renvoie l'URL d'autorisation. Après consentement, GET /oauth/notion/callback échange le code contre un token, crée la page dans l'espace du visiteur, puis jette le token et notifie la popup par postMessage. Le navigateur ne voit jamais le secret. La même plomberie OAuth resservira pour Jira, Linear ou Confluence.Tu es un expert en Product Management et stratégie OKR.
Génère des OKRs pour le produit suivant.
Règles importantes :
- Chaque Objective : qualitatif, inspirant, mémorable (sans chiffres)
- Chaque Key Result : mesurable, valeur cible précise et réaliste
- 3 Key Results par objectif
- Varie les types : metric / milestone / health
- Ancre les KRs dans les métriques fournies si disponibles
Réponds UNIQUEMENT avec un JSON valide :
{
"okrs": [{
"objective": "...",
"key_results": [
{"text": "...", "type": "metric", "baseline": "..."}
]
}],
"tips": ["conseil 1", "conseil 2", "conseil 3"]
}
| Outil | Température | max_tokens | Output |
|---|---|---|---|
| OKR Builder | 0.5 | 3 000 | JSON |
| Discovery Assistant | 0.7 | 2 000 | JSON |
| User Interview Analyzer | 0.4 | 3 000 | JSON |
| Backlog Prioritizer | 0.3 | 3 000 | JSON |
| Epic to User Stories | 0.4 | 4 000 | JSON |
| Roadmap Storyteller | 0.55 | 3 500 | JSON |
POST /rag-query : pipeline RAG sémantique complet (planner → retrieval → synthesis), natif dans le Worker, sans aucune dépendance externe.safeJsonParse(), gère les JSON entourés de blocs ```json que le LLM peut produire malgré les instructions strict JSON only.intent === 'pm_workflow', évite d'invoquer Workers AI pour les questions hors PM (portfolio, contact, tech).ctx.waitUntil), trace les appels sans alourdir le temps de réponse.POST /rag-query expose {reply, plan, chunks, engine: 'worker-rag-semantic'}, les chunks sont visualisés dans RAG Explorer avec leur source et score de similarité.| Étape | Modèle | Température | max_tokens | Latence p50 | Tokens typiques |
|---|---|---|---|---|---|
| Planner | gpt-oss-120b | 0.2 | 500 | ~1.2s | ~200–400 |
| Synthesis | gpt-oss-120b | 0.45 | 450 | ~1s | ~300–450 |
| Workers AI (RAG) | bge-small-en-v1.5 | , | , | ~200–400ms | 384 dims |
| Total /orchestrate-stream | , | , | , | ~2–3s | ~600–900 |
| Total /rag-query | , | , | , | ~2.5–5s | ~700–1000 |
/orchestrate-stream divise la latence perçue par ~3 : les premiers tokens s'affichent en ~400ms pendant que la synthesis continue. Pour /rag-query, l'embedding batch Workers AI ajoute ~200-400ms mais permet un retrieval sémantique sans infrastructure externe.| Usage | Input tokens | Output tokens | Coût / appel | 1 000 appels/mois |
|---|---|---|---|---|
| KRL1 orchestrate | ~500 | ~400 | ~$0.00032 | ~$0.32 |
| RAG query | ~700 | ~450 | ~$0.00038 | ~$0.38 |
| 6 outils PM (avg) | ~600 | ~1500 | ~$0.00099 | ~$0.99 |
| Service | Limite gratuite | Usage actuel |
|---|---|---|
| Groq API | 30 req/min · 1 000 req/jour · 8 000 tokens/min | Fallback auto sur gpt-oss-20b si 429 |
| Cloudflare Workers | 100 000 req/jour | Largement suffisant |
| Workers AI (embeddings) | 10 000 neurons/jour | ~200/req → ~50 appels/jour |
| Cloudflare KV | 100 000 reads + 1 000 writes/jour | < 100 writes/jour |
| Langfuse Cloud | 50 000 observations/mois | ~3 events/appel KRL1 |
| GitHub Pages | Illimité (fichiers statiques) | Frontend complet |
Mai 2026, refonte complète de la navigation : accordéon remplacé par 5 tabs avec chargement à la demande, et des liens nav qui n'apparaissent que lorsque le visiteur a dépassé le hero.
Architecture et Décisions produit sont désormais accessibles comme tabs dans l'index, chargées via fetch + DOMParser au premier clic. Chaque page reste une URL autonome. Le CSS injecté passe par scopeCSS(css, panelId) : chaque sélecteur est préfixé de l'ID du tab (#architecture .decision-card) pour confiner les styles : impossible d'écraser les glows du hero ou les variables globales. La navigation contextuelle repose sur un IntersectionObserver sur .tech-strip-label : les 5 liens de section apparaissent en stagger (60 ms par lien) dès que le visiteur dépasse la zone "Stack technique", et disparaissent instantanément au retour vers le hero.