Aller au contenu principal
IA

Partager toute la doc git d'un projet avec un fondateur non-dev (et son LLM) : 400 lignes, zéro Notion

Publié le9 min de lecture

Un endpoint HTTP qui sert un zip de toute la doc, deux skills Claude (lire la mémoire / proposer une PR), un PAT GitHub scopé : comment alimenter directement le LLM d'un fondateur non-dev sans Notion, sans compte GitHub, sans abonnement. Le pattern, les décisions techniques (UUID statique, default-deny, llms.txt), et les limites honnêtes — V1 codée, pas encore en main du fondateur.

Sur un Sprint Fondateur en cours, le CEO est un dirigeant non-dev. Il pilote, prend les décisions produit, alimente la roadmap. Et il a un LLM perso — Claude, en l'occurrence — avec lequel il travaille au quotidien. Ma question, deux semaines après le démarrage du projet : où est-ce que sa mémoire de projet vit ? Parce que si elle vit dans Notion, je sais déjà comment l'histoire se termine — un silo séparé du code, qui dérive en silence, et qui ne sait pas parler aux LLMs (le sien, les miens).

J'ai dit non à Notion. Pas parce que Notion est mauvais — il est très bien pour beaucoup d'équipes — mais parce que dans ce contexte précis, la doc projet doit être au même endroit que les ADR techniques, le modèle de données et les comptes rendus de RDV. C'est-à-dire dans le repo git. Le problème : un fondateur non-dev n'a pas de compte GitHub, pas de Git CLI, pas envie d'apprendre. Et ses sessions Claude ne savent pas, par défaut, où aller chercher cette mémoire.

J'ai donc écrit en deux heures un petit système qui résout ça : un endpoint HTTP qui sert toute la doc du repo dans un zip, ingérable par n'importe quel LLM via un skill custom. Et un second skill qui permet au fondateur de proposer une modif via une PR GitHub — sans jamais ouvrir GitHub. Cet article décrit le pattern, les décisions techniques que j'ai prises, et les limites que j'assume.

Pourquoi j'ai dit non à Notion (pour ce projet)

Le contexte mérite d'être posé. L'équipe Sprint Fondateur est minuscule : un fondateur non-dev, moi côté tech, deux consultants amis en support ponctuel (architecte, CDP IT). La doc projet contient les décisions produit, les ADR techniques, le modèle de données, les comptes rendus de RDV stratégiques, les notes de discovery, la roadmap. Toute la matière qui, dans une boîte plus grosse, vivrait dans Notion ou Confluence.

Notion impose cinq choses dans ce contexte précis :

  1. Un silo séparé du code. Dès qu'une décision technique évolue, la page Notion dérive. Personne ne pense à la mettre à jour quand un commit change la donne — parce que ce n'est pas dans le flow du dev.
  2. Un compte par membre. Friction immédiate pour onboarder l'architecte ami ou un nouveau prestataire ponctuel.
  3. Un abonnement mensuel. Coût récurrent pour une équipe de trois ou quatre. Marginal en valeur absolue, mais c'est un coût qui ne sert rien d'autre.
  4. Un vendor lock-in. Si on revend le projet, ou si on migre l'équipe, il faut exporter, reformatter, migrer.
  5. Aucune intégration LLM native. Ni mon Claude Code (qui code sur le repo), ni le Claude perso du fondateur ne peuvent lire Notion sans plumberie spécifique. On parle d'un workspace cloisonné en dehors du flow agentique.

Mais l'alternative « tout dans le repo git » exclut le fondateur. Il n'a ni git clone, ni gh pr create, ni envie d'apprendre — et il a raison de ne pas avoir envie. Son job, ce n'est pas Git. Son job, c'est de prendre des décisions et de les confronter à un LLM qui connaît tout le projet.

Le vrai problème à résoudre, donc, n'est pas « comment partager la doc » au sens humain. C'est : comment alimenter le LLM du fondateur avec exactement la même mémoire que celle qui pilote mes propres sessions Claude Code, et lui donner un moyen d'y contribuer.

La solution, en une URL

J'ai exposé un endpoint sur l'API du projet :

GET /_internal/memory/{uuid}

Le {uuid} est un UUID v4 statique, partagé une fois au fondateur via Signal. L'endpoint renvoie un fichier ZIP qui contient :

  • Toute la doc du repo (docs/**/*.md)
  • Un llms.txt auto-généré (le standard ouvert créé par Jeremy Howard / Answer.AI fin 2024, déjà adopté par Anthropic, Vercel, FastAPI, Tailwind)
  • Un README.md qui explique l'installation côté Claude
  • Deux skills Claude custom : memory-update et memory-pr
  • Un PAT GitHub fine-grained injecté à la volée dans les skills

Le flow opérationnel ressemble à ça :

Claude (côté fondateur)
        │
        │  /memory-update
        ▼
HTTPS GET /_internal/memory/{uuid}
        │
        ▼
API (rate limit 10/min/IP, log audit)
        │
        ├─► lit docs/**/*.md du repo
        ├─► génère llms.txt
        ├─► bundle skills + PAT + README
        ▼
   ZIP (~345 KB)
        │
        ▼
Mémoire LLM locale du fondateur

Plus tard, dans la même session :

Fondateur : « ajoute dans la doc qu'on a tranché X au RDV de jeudi »
        │
        │  /memory-pr "ajoute dans la doc qu'on a tranché X..."
        ▼
skill → API GitHub → branche + commit + PR
        │
        ▼
URL de PR retournée au fondateur
        │
        ▼
Je valide ou je refuse, en review GitHub classique

Côté fondateur, le setup tient en cinq minutes : il colle l'URL dans son Claude la première fois, lance /memory-update, et c'est fait. Pour mettre à jour sa mémoire ensuite (nouvelles décisions, nouveaux ADR), il relance /memory-update quand il en a envie. Pour proposer une modif, il décrit ce qu'il veut changer en langage naturel et le skill /memory-pr fait le boulot Git à sa place.

Côté dev (moi, mes sessions Claude Code), rien ne change : accès direct au repo, comme avant. C'est une couche de service par-dessus le même repo, pas une migration.

Le controller Symfony qui sert tout ça tient en une cinquantaine de lignes. La logique : valider l'UUID en constant_time_equals contre la variable d'env, rate-limiter, lire docs/, générer le llms.txt à la volée, packager le tout, streamer le zip. Une commande curl suffit à tester :

curl -o memory.zip https://api.projet.com/_internal/memory/<uuid>
# 200 + zip de 345 KB en ~130 ms

curl -i https://api.projet.com/_internal/memory/wrong-uuid
# 404 (pas 401, pas de fuite de signal)

# 11 requêtes rapides depuis la même IP
# → 429 Too Many Requests à la 11ème

Les décisions techniques qui valent d'être discutées

C'est la partie où je m'attendais à plus de débat interne — et où en pratique chaque choix a été assez vite tranché par contrainte de simplicité.

UUID statique au lieu d'OAuth. Un UUID v4 = 122 bits d'entropie. Inattaquable au bruteforce dans des temps raisonnables. La signature secrète, c'est l'URL elle-même, partagée en privé sur Signal. Setup pour le fondateur = zéro OAuth, zéro compte, juste une URL. Côté serveur, je rate-limite à 10 req/min/IP et je log chaque accès pour audit. Si demain je sens que c'est trop léger, je passe à un GitHub App OAuth — mais ce sera de l'over-engineering aujourd'hui.

PAT GitHub fine-grained bundlé dans le zip. Scopé Contents: R/W + Pull requests: R/W sur un seul repo. Expiration 90 jours, rotation trimestrielle au Makefile. Le pire scénario si le zip fuit : un attaquant peut ouvrir des PR sur un seul repo. Ces PR ne se mergent pas sans validation humaine, sont triviales à fermer, à supprimer en bloc, et le PAT est révoqué en deux clics. Pas de risque pour la prod, pas de risque pour les secrets (le PAT ne lit pas les workflows GitHub Actions ni les secrets repo). C'est un risque borné et réversible.

Pas de whitelist de fichiers. Si un doc est dans docs/, il est partageable. Convention simple : un doc privé va dans docs/internal/ ou commence par _private_. Je n'aime pas les allow-lists par fichier — c'est de la maintenance constante, ça finit toujours par oublier un doc, et la première fois que quelqu'un ajoute un nouveau type de doc personne ne pense à l'ajouter dans la whitelist. Une convention de dossier, c'est lisible à l'œil dans le tree.

Default-deny côté serveur. Si la variable d'env MEMORY_SHARE_UUID ou MEMORY_SHARE_GITHUB_PAT n'est pas configurée (cas par défaut en dev local et en CI), l'endpoint répond 503 memory_share_not_configured. Zéro chance d'exposer accidentellement la doc en environnement de dev qui aurait fuité sur un sous-domaine de prévisualisation. La configuration prod est explicite, par variable d'env, dans le pipeline de déploiement uniquement.

llms.txt en bonus. Le fichier est dans le zip, et il est aussi potentiellement servi à la racine du domaine public. Quand le site marketing du projet sera lancé, ChatGPT, Perplexity et les autres crawlers IA pourront lire directement le résumé de la doc sans intervention manuelle. C'est gratuit comme bénéfice — le format llms.txt est ouvert, court à générer, et Anthropic, Vercel, FastAPI, Tailwind l'exposent déjà sur leurs propres docs publiques. Mintlify le génère automatiquement dans son offre payante ; je le génère en trente lignes de PHP.

Bénéfices attendus et limites — la partie honnête

À l'heure où j'écris cet article, la V1 est codée. Le suite de tests PHP passe (1026 tests verts), la génération du zip prend environ 130 ms pour un payload de 345 KB sur le projet en cours, et j'ai testé manuellement les deux skills depuis ma propre session Claude. Mais je n'ai pas encore mis cette URL dans les mains du fondateur. Les bénéfices que je liste ci-dessous sont donc des extrapolations, basées sur ce que j'observe avec mes propres sessions Claude Code qui consomment déjà cette doc directement depuis le repo.

Bénéfices que j'attends.

  • Le fondateur peut interroger sa mémoire de projet en langage naturel. « Rappelle-moi les décisions du RDV du 12 mai » → son LLM lit le markdown des notes et résume.
  • Plus de désync Notion ↔ code. La doc évolue avec le commit qui change le code. git log est l'historique.
  • Onboarding d'un nouveau collab non-dev = une URL Signal. Pas de licence, pas de création de compte, pas de gestion de permissions individuelles.
  • Coût marginal nul. Le repo git est déjà là. Le PAT est gratuit. Le llms.txt se génère côté serveur en 30 ms.
  • Les LLMs du fondateur et les miens sont alimentés par la même source. Ça devrait drastiquement réduire les malentendus de type « ah mais je pensais que… » en RDV de cadrage.
  • Audit trail natif : qui a proposé quel changement, quand, validé par qui — c'est git log + GitHub PR review. Mieux que n'importe quel historique Notion.

Limites que j'assume.

  • Le fondateur n'écrit pas du markdown directement : il dicte à son LLM, qui structure. C'est moins direct qu'un éditeur WYSIWYG. Je l'accepte parce que le fondateur travaille déjà tout le temps avec son Claude — l'asymétrie d'effort est négligeable pour lui.
  • Le PAT statique impose une rotation manuelle tous les 90 jours. J'ai un Makefile pour ça mais c'est de la discipline humaine, pas de l'automatisation. Si je l'oublie un trimestre, le /memory-pr arrête de fonctionner, le fondateur me ping, je rotate.
  • Si le fondateur perd l'URL UUID, il faut la lui re-renvoyer en privé. Pas de portail self-service de récupération. C'est volontaire — ça force le rappel manuel d'authentification.
  • L'audit log est basique (un document Mongo par accès). Pas de dashboard. À itérer si le volume justifie un jour.
  • V2 envisagée mais pas prioritaire : une UI web lecture-seule pour quand le fondateur n'a pas son LLM sous la main, une recherche server-side, un GitHub App OAuth pour les équipes plus grandes. Je n'en ai besoin sur aucun projet aujourd'hui.

Pattern reproductible

Le pattern « endpoint serveur → zip de la doc + skills LLM + PAT scopé » est reproductible en ~1 jour de dev dans n'importe quelle stack avec un backend HTTP. Symfony, FastAPI, Express, Rails — peu importe. Tout ce dont tu as besoin, c'est :

  1. Un endpoint authentifié par URL signée (UUID statique ou JWT, peu importe).
  2. Une fonction qui lit ton dossier docs/, génère un llms.txt et package un zip.
  3. Un PAT GitHub fine-grained à expiration courte, injecté à la volée dans le bundle.
  4. Deux skills LLM côté client (lecture mémoire + proposition de PR).

Adapté aux petites équipes (1 dev + 1-5 non-devs) où Notion est une overhead. Pas adapté aux grosses équipes (>20) qui ont besoin de permissions fines par document — là, un Outline self-hosté ou un GitBook seront plus pertinents. Mais pour le segment startup early-stage avec un fondateur non-dev qui pilote au quotidien, c'est devenu mon défaut.

Cette approche s'inscrit dans une trajectoire que je décris ailleurs : faire du monorepo une mémoire vivante d'entreprise, et accepter que le code, le deck et la roadmap deviennent des artefacts régénérables tandis que la mémoire structurée devient le vrai actif. Le partage de cette mémoire aux non-devs — sans qu'ils aient à devenir devs — est l'angle mort de cette trajectoire. Cet article est ma première tentative de le combler proprement.

Si tu testes ce pattern dans ta stack, écris-moi. Je suis curieux de voir comment les contraintes de ton contexte changent les décisions techniques — notamment sur la partie auth (PAT vs GitHub App vs OAuth) et sur le format du bundle.

Envie d'en discuter ?

Réservez un créneau de 30 minutes pour un premier échange. Je vous aiderai à y voir plus clair sur votre situation.

Prendre rendez-vous