# ASPIC — Réflexions stratégiques *Document séparé du journal de développement technique et de la documentation utilisateur. Rassemble les échanges à vocation stratégique/business autour du projet ASPIC et du projet d'agence de Jean-Marc — pas de décisions d'architecture ou de code ici (voir le journal de développement pour ça).* Démarré le 28 août 2026, lors d'une session explicitement dédiée aux aspects stratégiques (pas de réalisation de fonctionnalités). ## 1. Contexte du projet d'agence Jean-Marc prépare la création d'une agence début 2027, pour proposer à des entrepreneurs (dans un premier temps en Bretagne) des solutions utilisant l'IA. En formation actuelle sur les outils du secteur. Position assumée dès le départ : refus d'appuyer son offre sur des outils no-code/low-code (Airtable, Lovable, Softr, etc.), pour des raisons à la fois techniques (limites structurelles, dépendance) et économiques (coûts récurrents mal adaptés à sa clientèle cible de petites structures). C'est ce qui a motivé l'acquisition du VPS et le choix d'architecture PHP+MySQL+JS vanilla d'ASPIC (voir journal de développement, section 1). ASPIC, initialement pensé comme un CRM interne "ersatz d'Airtable", est en train d'évoluer dans la tête de Jean-Marc vers quelque chose de potentiellement plus ambitieux (CRM enrichi en IA). Ce document capture la réflexion sur ce que ça implique, sans que rien ne soit tranché à ce stade. ## 2. Capacité à suivre le projet dans la durée — Claude, abonnement, Git - **Croissance du projet et capacité de Claude à le suivre :** pas de rupture technique attendue tant que la discipline déjà en place est maintenue (journal de développement à jour, architecture en petits fichiers dédiés par écran/endpoint, sessions qui redémarrent "à froid" en relisant le projet plutôt qu'un fil de discussion qui s'éternise). Le vrai facteur de risque identifié n'est pas la taille du projet mais l'absence de contrôle de version (pas de Git à ce stade — livraison par transfert FTP avec versionnage manuel côté Jean-Marc). **Décision : installer Git, non urgent.** **Mise à jour du 28 août 2026 (matin) : Jean-Marc traitera l'installation de Git dans la session dédiée au projet de gestion du serveur, pas dans ce projet-ci — hors périmètre d'ASPIC à proprement parler.** - **Git et confidentialité :** clarifié que Git est un outil neutre (gestion de versions), pas intrinsèquement public — la confidentialité dépend uniquement de l'endroit où le dépôt est hébergé. Option recommandée compte tenu de la philosophie du projet : dépôt Git privé auto-hébergé sur le VPS (type Gitea/Forgejo), cohérent avec le refus des dépendances SaaS tierces déjà appliqué à ASPIC. Alternative : dépôt privé chez un hébergeur (GitHub/GitLab), également possible. - **Abonnement Anthropic et sessions parallèles :** vérifié via la documentation officielle — les limites d'usage (Pro/Max) sont un budget partagé par fenêtre de 5h + plafond hebdomadaire, commun à tous les produits Claude du compte, **pas** un compteur de sessions simultanées autorisées. Rien n'empêche déjà aujourd'hui de faire tourner plusieurs sessions en parallèle sur différents ordinateurs ; monter en gamme (Max 5x/20x) élargit le budget d'usage disponible pour soutenir cet usage sans buter sur les plafonds, mais ne "débloque" pas la fonctionnalité elle-même. Point non vérifiable avec certitude via la doc publique : existence ou non d'une limite technique dure sur le nombre de connexions simultanées, indépendante du budget d'usage. Point de vigilance à garder si le parallélisme devient réel : plusieurs sessions ne partagent pas un "cerveau" commun en temps réel, chacune ne sait que ce qu'elle relit (journal + doc utilisateur) — d'où l'intérêt de Git si plusieurs sessions doivent un jour toucher les mêmes fichiers. ## 3. Confidentialité des données — compte Anthropic Question posée par Jean-Marc : garantie que le développement d'ASPIC (code, réflexion business) ne soit pas utilisé par Anthropic pour l'entraînement de ses modèles. - Deux régimes distincts chez Anthropic : les comptes professionnels (Claude for Work, Team, Enterprise, API) n'utilisent pas les conversations pour l'entraînement par défaut (confirmé par la documentation officielle), sauf participation explicite au "Development Partner Program". Les comptes grand public (Free/Pro/Max) ont un réglage dédié dans Paramètres → Confidentialité ("Contribuer à améliorer nos modèles d'IA"). - **Vérifié et désactivé par Jean-Marc le 28 août 2026** sur son compte actuel (rattaché à "jmp.ia.bzh@gmail.com's Organization"). - **Point à ressurveiller** si l'abonnement change de nature plus tard (ex. bascule vers un plan de type Claude for Work) — Jean-Marc en a pris note lui-même. ## 4. La tentation GoHighLevel — usage-pont temporaire, pas fondation de l'offre Contexte : des formateurs contactés par Jean-Marc pour monter en compétence lui ont proposé GoHighLevel (outil marketing/CRM tout-en-un, ~97$/mois minimum en entrée de gamme, jusqu'à 497$/mois pour le mode "agence revendeuse en marque blanche") plutôt que de lui apprendre à construire l'équivalent lui-même, avec une promesse d'"accès gratuit". **Position de Jean-Marc, clarifiée après une première incompréhension de Claude sur ce point :** aucune intention de bâtir l'offre de sa future agence sur GoHighLevel. La réflexion porte uniquement sur un usage-pont temporaire, pour sa propre prospection, en attendant qu'ASPIC soit opérationnel — avec deux bénéfices visés (efficacité immédiate + étude des fonctionnalités pour inspiration future d'ASPIC) et une condition non négociable : pouvoir exporter ses données et les supprimer le jour de la bascule vers ASPIC. **Mise à jour du 28 août 2026 (soir) — offre confirmée par les formateurs :** gratuité annoncée pendant au moins un an (pas un simple essai de 14 jours), justifiée par des "relations privilégiées avec un responsable chez GHL" ; export des données annoncé comme total et sans restriction. Jean-Marc reste prudent et n'a rien signé. Point d'intérêt fonctionnel repéré au passage : publication automatisée sur Instagram, qui élargit le champ (pas seulement la prospection) — utile comme source d'inspiration pour ASPIC. Points de vigilance actés pour la suite : - Demander cet engagement de gratuité par écrit (email de confirmation, conditions précises, ou le compte lui-même une fois ouvert affichant clairement la durée) plutôt que de se fier à la parole rapportée d'intermédiaires ayant un intérêt commercial à la signature — une "relation privilégiée" informelle avec une personne chez GHL peut s'éteindre sans que ça dépende de Jean-Marc. - Vérifier l'export réellement, une fois le compte ouvert, sur des données de test — pas se fier à la garantie verbale, même donnée de bonne foi (même discipline que pour tous les autres sujets de cette session : tester plutôt que croire sur parole). - Si sous-compte chez un tiers plutôt que compte à son nom propre : qui est propriétaire du compte parent, et devenir des données en cas de rupture de la relation. - Richesse réelle de l'export (CSV basique vs historique complet des interactions) et volet RGPD (données de prospects réels) — non traités en profondeur, juste signalés comme points à ne pas négliger. - Nouveau, lié à la fonctionnalité Instagram repérée : connecter GHL à un compte Instagram/Meta professionnel expose une catégorie de donnée différente (des accès/jetons, pas de simples enregistrements) — prévoir, le jour du retrait, de révoquer proprement cet accès en plus d'exporter les données. **Alternative explorée en parallèle (voir section 9) : Hostinger Agents + Google Sheets, jugée par Jean-Marc moins risquée pour ses vraies données que GHL, le chemin d'export/sortie y étant mieux compris et mieux documenté.** GHL reste une option à tester en parallèle (données factices), les deux pistes n'étant pas exclusives l'une de l'autre. ## 5. Modèle de commercialisation futur d'ASPIC — hypothèse de travail, non tranchée Projection à ~1 an : si un marché se confirme pour déployer ASPIC chez des clients, deux modèles distincts identifiés, avec des implications différentes : - **(a) Éditeur logiciel sous licence, déployé chez chaque client** — proche de la vision de portabilité initiale du projet (section 6 du journal de développement). Écarté par Jean-Marc pour ASPIC lui-même : risque de dissémination du produit hors de son contrôle ("faire des petits"), cohérent avec un constat déjà posé dans le journal le 22 août — aucune protection réelle n'existe pour du PHP/JS vanilla livré tel quel sur un hébergement mutualisé bas de gamme. **Reste autorisé et prévu :** déployer des solutions spécifiques "one-shot" chez des clients, réutilisant la même pile technique (MySQL/PHP/JS) et les mêmes conventions/méthodes de travail, sans que ce soit le produit ASPIC lui-même. - **(b) SaaS centralisé, hébergé et opéré par Jean-Marc, licence annuelle** — hypothèse ouverte, non tranchée. Réglerait le problème de protection IP du point (a) (le code ne quitte jamais le serveur de Jean-Marc), mais implique une responsabilité opérationnelle bien plus lourde (uptime, sauvegardes, sécurité, support) pour l'ensemble des clients simultanément — à intégrer dans le calcul du prix de la future licence, par comparaison avec le tarif GoHighLevel (~1200$/an) qui finance en partie ce type d'infrastructure. **Dimensionnement technique envisagé si (b) est un jour retenu** (réflexion préliminaire, pas un plan d'exécution) : repère de départ = VPS Hostinger haut de gamme (offre KVM 8 : 8 vCPU / 32 Go RAM / 400 Go NVMe, ~26 à 74$/mois selon promo), plausible pour plusieurs dizaines de clients TPE en usage CRUD léger comme ASPIC. Modèle d'isolation recommandé : une base MySQL séparée par client sur une même instance (isolation de sécurité + export/suppression facile par client, pas de colonne "client_id" partagée), plutôt qu'un partitionnement sur plusieurs instances MySQL ("un MySQL tous les x clients") — cette dernière option à réserver pour plus tard, seulement si une vraie tension de charge est constatée (même principe "pas de sur-ingénierie" déjà appliqué dans ASPIC). **Précision de Jean-Marc (28 août) : il imagine plutôt ce partitionnement futur par lots (ex. 10 bases par instance, puis une nouvelle instance pour les 10 suivantes) que par isolement nommé d'un client précis — les deux motifs sont couverts par le même mécanisme d'annuaire, voir section 8.** ## 6. Séquencement retenu Priorité assumée aux prestations "one-shot" immédiatement rémunératrices dès le lancement de l'agence — ASPIC continue de mûrir en parallèle, sans précipitation ni pression de délai pour en faire un produit vendable. Les missions one-shot ne sont pas vues comme une perte de temps face au produit : elles sont l'occasion de repérer, sur des cas réels et payés, quels besoins reviennent assez souvent pour mériter d'être un jour généralisés — même logique que la règle déjà en place dans le code d'ASPIC ("généraliser à partir de 3 répétitions concrètes constatées"), appliquée ici au niveau du choix business plutôt que du code. Bascule progressive vers le produit envisageable si le marché confirme un potentiel réel ; sinon, Jean-Marc reste focalisé sur les prestations one-shot (pas de "lâcher la proie pour l'ombre"). ## 7. Nom de domaine aspic.bzh — environnement de test **Acheté par Jean-Marc le 28 août 2026 au soir**, chez OVH (seul registrar habilité pour le `.bzh`). Éligibilité déjà acquise dans les faits (Jean-Marc en contact avec l'association gestionnaire du `.bzh`, basée à Quimper, qui lui a déjà accordé la possibilité de créer des noms à deux lettres). Hébergement technique déjà cadré : DNS pointé chez OVH vers l'IP du VPS (même principe déjà en place pour `ms.bzh`), routage via Nginx Proxy Manager déjà en place sur le VPS. **Décision de Jean-Marc : ne pas se précipiter sur la mise en œuvre technique, à reprendre "dans quelques jours, sans stress".** Voir section 8 pour l'architecture d'accès multi-environnements envisagée (routage par annuaire), qui reste une réflexion conceptuelle non implémentée à ce stade. **Mise à jour du 1er septembre 2026 — migration vers un sous-domaine :** l'environnement de bêta test de l'application, jusque-là sur la racine `aspic.bzh`, est déplacé vers `crm.aspic.bzh`. Objectif explicite : garder la racine `aspic.bzh` libre pour y installer, dans quelques mois, un petit site de promotion de la solution — si la situation évolue favorablement dans ce sens (rien n'est encore engagé sur ce site vitrine à ce stade, c'est une réservation d'usage plutôt qu'un chantier commencé). Conséquence terminologique pour la suite de ce document : dans la section 8 ci-dessous, rédigée avant cette migration, les mentions d'« `aspic.bzh` » comme environnement applicatif de test désignent techniquement `crm.aspic.bzh` depuis le 1er septembre — laissées telles quelles pour ne pas réécrire une réflexion déjà actée, mais à lire avec cette correspondance en tête. ## 8. Architecture d'accès pour aspic.bzh — routage par identifiant, annuaire, cohabitation avec aspic.mvl-tls.fr (28 août 2026) *Voir la mise à jour du 1er septembre 2026 en fin de section 7 : les mentions d'« aspic.bzh » ci-dessous, comme environnement applicatif de test, désignent depuis cette date `crm.aspic.bzh` — la racine `aspic.bzh` étant réservée au futur site de promotion.* Réflexion engagée par Jean-Marc, explicitement conceptuelle à ce stade ("sans passer à l'action maintenant") — aucune implémentation en cours. **Choix de principe validé par les deux :** un seul point d'entrée (`aspic.bzh`), pas de sous-domaine par client. Jean-Marc ne souhaite donner aucune indication de l'existence d'un client via l'URL (pas de `toto.aspic.bzh` visible par un curieux). Le routage vers la bonne base de données se ferait donc par l'identifiant saisi à la connexion, pas par l'adresse. **Mécanisme envisagé :** un petit annuaire central (une table séparée des bases clients, ne contenant aucune donnée métier — uniquement une correspondance identifiant → informations de connexion à la bonne base). L'identifiant de connexion évoluerait vers un format structuré (ex. `code_client-code_user`, dans l'esprit du USR_Code actuel à 3 caractères mais globalement unique) plutôt qu'un email, pour rester cohérent avec la lisibilité déjà recherchée dans les journaux (REA_CodeUser/OPE_CodeUser). Flux de connexion : l'app consulte d'abord l'annuaire avec l'identifiant saisi pour déterminer la base cible, puis vérifie le mot de passe dans cette base précise. **Anticipation d'une évolution vers plusieurs instances MySQL (pas seulement plusieurs bases sur une même instance) :** l'annuaire, dès sa conception, porterait pour chaque client une adresse de connexion complète (serveur + port + base), pas seulement un nom de base — même si, par défaut, tous les clients pointent vers le même serveur au départ. Ça permet de déplacer un client (ou un lot de clients) vers une instance MySQL séparée plus tard sans réécrire l'application, seulement en modifiant une ligne de l'annuaire. Jean-Marc envisage ce besoin futur plutôt sous forme de paliers de charge (ex. 10 bases par instance, puis une nouvelle instance pour les 10 suivantes) que sous forme d'isolement nommé d'un client précis — les deux cas de figure sont couverts par le même mécanisme, sans qu'il faille choisir maintenant lequel se produira. **Relation entre les environnements, clarifiée :** - `aspic.mvl-tls.fr` reste le bac à sable de développement (données de test, fonctionnalités en cours de maturation), complètement séparé (déploiement, base) de `aspic.bzh`. - `aspic.bzh` porte **une seule version** de l'application (celle jugée aboutie), jamais deux versions en parallèle. Sur cette version unique cohabiteraient plusieurs bases : celle de Jean-Marc pour son usage réel, une base de démonstration pour les prospects (à peupler de données fictives, avec réinitialisation périodique envisagée pour ne jamais laisser de trace d'une démo à l'autre), et plus tard celles de vrais clients si le modèle (b) de la section 5 se concrétise. Le passage d'une fonctionnalité du bac à sable vers la version unique de production se fait par promotion, une fois la fonctionnalité validée — pas de duplication de code à maintenir. - Confirmé explicitement par Jean-Marc : ce n'est donc pas "deux versions différentes" de l'application selon l'usage (personnel vs démo), mais une seule version servant plusieurs bases isolées. ## 9. Hostinger Agents + Google Sheets — piste explorée comme alternative à GoHighLevel (28 août 2026) En marge de sa recherche d'un serveur Hostinger plus puissant, Jean-Marc a découvert "Hostinger Agents" — une offre d'agents IA spécialisés par fonction (SEO, Marketing, Réseaux sociaux, Contenu, **Sales Agent** — prospection et relance), ~7 à 10$/mois selon l'engagement (1000 crédits/mois, 150+ compétences), connectables à un catalogue d'applications tierces préconfigurées (Gmail, Outlook, HubSpot, Notion, Jira, GitHub, Google Drive, etc.). **Idée de Jean-Marc, jugée pertinente par Claude :** séparer la couche IA/automatisation (louée, bon marché, jetable) de la couche données (ASPIC, chez lui, jamais confiée à un tiers) — contrairement à GHL, où l'outil devient lui-même le coffre-fort des données. **Points vérifiés par Claude à date :** - Connexion à une API personnalisée/webhook générique : **non confirmée** dans la documentation publique de Hostinger Agents (liste de connecteurs fermée, ~20 applications nommées). Hostinger propose par ailleurs du n8n en self-hosted comme produit d'hébergement séparé, et un connecteur n8n pour piloter *leur propre API d'hébergement* — mais rien ne confirme que l'agent commercial puisse être relié à n8n comme intermédiaire. **À vérifier directement dans les paramètres de l'agent une fois un compte ouvert — pas encore fait par Jean-Marc au 28 août au soir.** - **Jean-Marc gère déjà n8n en auto-hébergé sur son VPS** (dans le cadre du projet de gestion du serveur, aux côtés de PostgreSQL/MySQL/LangFlow), indépendamment de l'offre Hostinger — la question de la compétence à acquérir sur n8n est donc caduque, il l'opère déjà. - Politique de confidentialité de Hostinger Agents (page officielle vérifiée) : conversations stockées et liées au compte Hostinger, **explicitement non utilisées pour entraîner/affiner leurs modèles d'IA**, jamais partagées à des tiers à des fins publicitaires. Fournisseur du modèle IA sous-jacent (OpenAI, Anthropic, autre) **non précisé** dans la documentation publique — point resté ouvert. - Nuance importante actée : cette politique ne couvre que la conversation avec l'agent Hostinger lui-même. Une donnée écrite ensuite dans un Google Sheet connecté tombe sous la politique de confidentialité de Google, distincte — deux périmètres de confiance empilés, pas un seul. **Piste retenue par Jean-Marc pour une première mise en pratique, explicitement double temporaire :** 1. Utiliser Google Sheets (confirmé dans le catalogue de connecteurs standards) comme tampon de contrôle visuel — l'agent y écrirait ses résultats, et y lirait potentiellement les données à traiter en entrée (les agents ne semblant pas porter de base de données propre — un agent "sans mémoire" doit être alimenté à chaque tâche). Cette étape validerait au passage que le format de données échangé est compatible avec une future intégration dans ASPIC ; les fichiers Google Sheets ainsi produits seraient temporaires par nature. 2. Une fois les fonctionnalités utiles réellement intégrées nativement dans ASPIC, abandon prévu des agents Hostinger loués — solution de transition assumée comme telle, pas une brique d'architecture définitive. **Nuance apportée par Claude sur la réduction du risque via ce montage :** la nécessité de nourrir l'agent en données d'entrée n'est pas propre à cette approche (tout outil, y compris GHL, a besoin d'être alimenté). Le vrai avantage structurel par rapport à GHL n'est donc pas "moins besoin de données", mais l'absence de copie persistante et complète des données sensibles chez le prestataire — bénéfice réel uniquement si l'alimentation de l'agent est conçue pour ne fournir, à chaque tâche, que la tranche de donnée strictement nécessaire (pas un accès large et permanent à l'ensemble d'une feuille ou d'une base) : un choix de conception à faire consciemment, pas une garantie automatique. **Point technique accessoire vérifié, à valeur générale pour tout usage de tableur (Excel ou Google Sheets) en amont d'ASPIC :** le format d'affichage spécial "Code postal" d'Excel est purement cosmétique — la valeur réellement stockée reste numérique, sans le zéro de tête, et c'est cette valeur qui part dans un export CSV ou une lecture programmatique. Seul un formatage explicite en texte protège réellement la donnée. Google Sheets ne propose même pas ce format spécial d'affichage. Même vigilance que celle déjà actée dans le journal de développement pour CNT_AdrCP. **Statut au 28 août 2026 (soir) : Jean-Marc n'a pas encore avancé sur la vérification des fonctionnalités/connecteurs Hostinger Agents.** Reste à faire : existence d'un connecteur générique/API personnalisée, identité du fournisseur de modèle IA sous-jacent. ## 10. Répondeur téléphonique intelligent — projet distinct, exploration initiale (1er-2 septembre 2026) *Section volontairement séparée de tout ce qui précède : ce n'est pas un chantier ASPIC, mais un projet à part que Jean-Marc envisage de développer en parallèle — capturé ici parce que la discussion en est partie d'un point technique abordé côté ASPIC (le pilotage vocal, voir journal de développement section 27) mais dépasse largement ce cadre.* **Origine de la discussion :** en travaillant sur le pilotage vocal d'ASPIC, Jean-Marc s'est demandé si la reconnaissance de commandes allait rapidement nécessiter des bases de données vectorielles (PostgreSQL/pgvector), redoutant que ça complique sérieusement le sujet. Réponse apportée : pas pour le pilotage vocal d'ASPIC dans sa forme actuelle — un ensemble borné et restreint de commandes/intentions relève d'une simple classification par mots-clés/regex, pas d'une recherche sémantique ; une base vectorielle serait de la sur-ingénierie pour ce cas précis. Jean-Marc a alors précisé que ce besoin allait en revanche réellement se poser pour un autre projet qu'il envisage : un **répondeur téléphonique intelligent**, branché sur une ligne téléphonique. **Compréhension du principe, confirmée par Jean-Marc :** l'assemblage de plusieurs briques distinctes — transformation de la voix de l'appelant en texte (un peu comme le fait le pilotage vocal côté ASPIC), interrogation d'une base de connaissances via recherche vectorielle (pour retrouver l'information ou la réponse pertinente dans un corpus potentiellement large et ouvert, contrairement au jeu de commandes fermé d'ASPIC), puis transformation de la réponse en voix de synthèse — le tout avec une contrainte de latence forte et explicitement nommée par Jean-Marc : l'interlocuteur humain au bout du fil ne doit à aucun moment se demander si "la personne en face s'est endormie". C'est cette contrainte de réactivité en temps quasi réel, combinée à un corpus de connaissances potentiellement vaste et évolutif (contrairement à la liste fermée de commandes du pilotage vocal ASPIC), qui justifie cette fois le recours à une base vectorielle — la nuance posée par Claude étant que le besoin vient de la nature du problème (recherche sémantique sur corpus ouvert) et pas de la voix en tant que telle. **Infrastructure déjà disponible sur le VPS de Jean-Marc, repérée en marge du débogage du pilotage vocal** (`docker ps -a`, 2 septembre 2026) : une instance **PostgreSQL avec l'extension pgvector** (`pgvector/pgvector:pg16-trixie`) tourne déjà, aux côtés de **n8n** (déjà utilisé et évoqué comme brique d'orchestration possible pour l'interprétation des dictées du pilotage vocal, section 27 du journal) et de **LangFlow** (outil de composition de flux IA, potentiellement pertinent pour assembler les briques voix→texte→recherche→texte→voix de ce futur répondeur). Rien n'indique que ces instances aient été mises en place spécifiquement pour ce projet — probablement des briques déjà expérimentées pour d'autres besoins — mais elles constituent une base technique déjà en place le jour où Jean-Marc voudra vraiment démarrer ce chantier, sans avoir à réinstaller quoi que ce soit. **Statut : simple exploration conceptuelle, aucun développement engagé.** Jean-Marc a explicitement mis ce projet de côté pour revenir au pilotage vocal d'ASPIC. À reprendre le jour où il voudra s'y consacrer, avec cette base d'infrastructure déjà cadrée. ## 11. Le "bureau à l'ancienne" — délégation à plusieurs assistants IA nommés (réflexion long terme, 2 septembre 2026) **Origine.** Née en marge des essais du pilotage vocal multi-agents (voir journal de développement, section 27) : une fois plusieurs assistants nommés distincts (Viktor, Matilda...) capables de recevoir des consignes vocales chacun sur son périmètre, Jean-Marc a partagé une vision plus large pour l'évolution de l'interface d'ASPIC à long terme. **Le principe.** Remplacer les écrans CRUD traditionnels par une métaphore de bureau à l'ancienne : un tableau de liège avec des post-its de couleur, un par assistant IA, des dossiers de vérification, un agenda, un téléphone. L'utilisateur délègue oralement à plusieurs assistants nommés, chacun responsable d'un périmètre (voir `AGN_Fonction` dans `ASP_Agents` — Agent Commercial, Agent Administratif...). Différence assumée avec une assistante humaine : un agent IA n'a pas la faculté de procrastiner ou de remettre une tâche à plus tard sans raison — il agit, ou explique pourquoi il n'a pas pu. **Interface volontairement basique.** Pas une interface "sexy" ou soignée visuellement — la valeur réelle est vue comme résidant dans la structure des données et la couche de délégation, pas dans l'habillage visuel. Cohérent avec la philosophie déjà en place dans ASPIC (pas de sur-ingénierie, PHP/JS vanilla plutôt que framework). **Périmètre et statut.** Vision explicitement limitée à ASPIC lui-même à ce stade, pas un projet d'outillage plus large. Jean-Marc reconnaît que cette réflexion peut évoluer avec l'expérience acquise sur le terrain — voir justement le principe ci-dessous, tiré d'un premier retour d'expérience concret le jour même. Aucun développement engagé — pure réflexion à ce stade, capturée ici pour mémoire. **Principe de conception qui en découle, tiré de l'expérience réelle du pilotage vocal (2 septembre 2026) :** mieux vaut choisir des noms d'agents qui passent bien nativement à la reconnaissance vocale que d'empiler des tolérances pour rattraper un nom mal choisi — chaque tolérance ajoutée étant à la fois un risque de faux déclenchement (si elle recoupe un mot français courant) et un pari sur un seul accent/une seule prononciation testée, fragile face à la diversité réelle des utilisateurs. Deux agents (Lilou, Karl) ont été retirés sur cette base après des essais répétés peu concluants, plutôt que d'être maintenus à coups de correctifs successifs. Principe à garder en tête si le "bureau à l'ancienne" se concrétise un jour avec davantage d'assistants nommés. ## 12. Interpréter le pilotage vocal sans s'effondrer à l'échelle — LLM à sortie structurée pour l'action, RAG réservé à la recherche (3 septembre 2026) **Origine — un enjeu concurrentiel identifié via un tiers.** Jean-Marc a montré les évolutions du pilotage vocal à sa compagne, qui a immédiatement fait le rapprochement avec sa propre expérience professionnelle : elle travaille dans une grosse PME équipée de SAP, confrontée au quotidien à une application qui rame pendant de longues minutes, des arrêts brutaux, et des procédures extrêmement lourdes pour la moindre intervention (créer un utilisateur, corriger un bug de saisie) — délai moyen de 2 à 3 jours via un prestataire externe. Jean-Marc en tire une conviction stratégique : le pilotage vocal, davantage qu'un simple confort, pourrait devenir un vrai argument différenciant face à ce type d'outil lourd, auprès de futurs clients de son agence. **Conséquence directe sur l'exigence de qualité :** cette perspective augmente la pression de fiabilité plutôt que de la relâcher — Jean-Marc redoute explicitement le scénario inverse ("sympa en démo, mais ça ne marche pas en vrai"), d'autant qu'il ne croit pas à la viabilité d'un empilement de règles/rustines au cas par cas une fois le pilotage vocal étendu bien au-delà de la ToDoList (contacts, catalogue, devis et affaires en cours, facturation). **Deux problèmes distincts, à ne pas confondre sous un seul chantier.** Discussion posée avec Claude pour trancher cette inquiétude : - **La reconnaissance du mot déclencheur** (l'épisode Lilou/"les loups", voir journal de développement section 27) est un problème de transcription audio, en amont de tout traitement — aucune base vectorielle, aucun RAG, aucun LLM n'y changerait quoi que ce soit, c'est une limite de la reconnaissance vocale elle-même (la même que rencontrent Alexa, Siri ou Google Home). Déjà traité par le choix de noms qui passent bien à l'oral et par `AGN_Variantes` piloté en base — et point rassurant pour la suite : cette surface d'erreur ne grandit pas avec le nombre de modules d'ASPIC, elle reste bornée au nombre d'agents nommés. - **L'interprétation d'une dictée déjà bien captée** — transformer "il faut ajouter un contact, il s'appelle Pierre Chartier, il est plombier à Quimper..." en une action structurée (quel module, quelle opération, quels paramètres) — est un problème différent, qui se posera réellement une fois la ToDoList suivie par la gestion des contacts, du catalogue, des devis, de la facturation. **Pourquoi le RAG/pgvector n'est pas l'outil pour ce deuxième problème.** Un RAG/base vectorielle sert à retrouver de l'information pertinente par similarité sémantique dans un corpus large et non structuré — une recherche, pas un déclenchement d'action. C'est l'outil du **répondeur téléphonique intelligent** (section 10 ci-dessus), où le besoin est justement de chercher une réponse dans une base de connaissances ouverte, avec une contrainte de latence quasi temps réel. Le pilotage vocal d'ASPIC, même étendu à plusieurs modules, reste un ensemble d'actions **enumérable et borné** (créer un contact, ajouter une ligne de devis, appliquer une remise...) — la bonne réponse est un LLM à sortie structurée (function calling) : on lui fournit un catalogue d'actions disponibles (nom, paramètres attendus, endpoint concerné), il renvoie l'action reconnue et ses paramètres extraits du texte, sans deviner s'il n'est pas sûr. Chaque nouveau module ajoute des entrées à ce catalogue, pas du code d'interprétation nouveau — c'est ce qui évite l'empilement de règles redouté par Jean-Marc, bien mieux qu'une base vectorielle qui ne répond pas à ce besoin précis. Le RAG garde sa place légitime, mais ailleurs : recherche floue dans un futur catalogue produits ("quelle référence pour un connecteur étanche IP67 20A"), ou dans l'historique des devis/affaires — pas pour interpréter une commande. L'infrastructure (PostgreSQL/pgvector, n8n, LangFlow) tourne déjà sur le VPS de Jean-Marc, prête sans réinstallation le jour où un vrai besoin de ce type apparaîtra (voir section 10). **Modèle affiné pour le retour visuel à l'utilisateur : deux statuts distincts, pas un seul niveau de confiance.** Proposition initiale de Claude (un seuil de confiance unique) affinée par Jean-Marc, qui avait déjà anticipé le besoin d'une correction ou d'une validation propre à l'action demandée : - **"À corriger"** — l'IA n'a pas réussi à comprendre proprement la demande (information manquante, incohérente, ou dictée incompréhensible). Un problème d'interprétation, détecté par le LLM lui-même au moment de faire correspondre la dictée à une action du catalogue. - **"À valider"** — l'IA a bien compris et préparé l'action, mais cette action précise exige toujours un accord humain avant de partir pour de vrai (ex. l'envoi d'un devis à un client), **indépendamment du niveau de confiance de l'interprétation** — une propriété portée par l'action elle-même dans le catalogue, pas un seuil réglé globalement. Jean-Marc a proposé un signe graphique sur le post-it de l'assistant pour identifier ce qui l'attend (un point d'interrogation, par exemple) — retenu pour "à corriger" (il doit apporter une information ou trancher une ambiguïté). Un second signe, distinct, est envisagé pour "à valider" (un geste plus simple, oui/non, sur quelque chose déjà prêt) — non choisi à ce stade, pour que les deux situations restent reconnaissables d'un coup d'œil sans ouvrir le post-it. **Rôle de n8n confirmé, dans les mots de Jean-Marc : un "agent de veille" réagissant à des déclencheurs programmés** — pas un outil interrogé à la demande. Concrètement, soit une surveillance périodique des nouvelles clôtures de notation, soit un appel direct dès la clôture d'une dictée pour plus de réactivité — un réglage à choisir plus tard, pas une contrainte d'architecture. **Décision pour la suite immédiate : ne pas concevoir les règles d'interprétation à l'avance, constituer d'abord un corpus réel.** Cohérent avec la leçon déjà tirée de Lilou/"les loups" — ce qui paraît naturel en le pensant seul se révèle différent une fois dicté réellement et de façon détendue. Jean-Marc en a fourni la preuve lui-même, avant même d'avoir l'outil en main : il a par exemple relevé qu'il commence souvent une instruction par "il faut"/"il faudrait" plutôt que par le prénom d'un agent, et utilise aussi bien "puis" que "ensuite" pour enchaîner deux idées — deux détails qu'aucune conception à la table n'aurait fait ressortir aussi vite. Voir journal de développement, section 27, pour l'outil concret construit ce soir-là (`micro_test.js`/`dictees_test.php`, table `ASP_DicteesTest`) : aucune règle d'interprétation n'y est codée, volontairement — l'objectif de cette phase est uniquement d'accumuler la matière première (dictées réelles, y compris les essais ratés) qui permettra, plus tard, de concevoir le catalogue d'actions et les règles d'extraction avec des exemples réels plutôt qu'hypothétiques. **Statut : orientation actée, aucun développement de la couche d'interprétation elle-même engagé.** Le développement immédiat porte uniquement sur la constitution du corpus (voir journal, section 27) — le catalogue d'actions, l'appel LLM à sortie structurée et les deux signes graphiques du post-it restent à concevoir, une fois ce corpus jugé suffisant. **Addendum du 3 septembre 2026 (nuit) — la reconnaissance brute d'un mot rare/inventé est un problème à part, que ni le LLM d'interprétation ni le RAG ne résolvent.** Les premiers essais réels de Jean-Marc sur le thème "Gestion des Contacts" (voir journal, section 27) ont fait remonter, en marge de la constitution du corpus, un problème concret qui recoupe la distinction posée plus haut mais s'y ajoute : la dictée d'une adresse mail échoue très souvent, pour trois raisons distinctes — un vocabulaire de ponctuation dicté ("point", "tiret", "arobase") converti de façon incohérente par le moteur gratuit du navigateur, une segmentation de la dictée en plusieurs lignes non fiable, et surtout des lettres purement et simplement avalées sur des mots sans aucun support linguistique réel (ex. "mvl-tls.fr" transcrit "mvtls.fr") — cette dernière étant une perte acoustique en amont de tout traitement, jamais rattrapable par un post-traitement quel qu'il soit, contrairement aux deux premières. Point explicitement acté avec Jean-Marc : **aucune solution, gratuite ou payante, ne garantit un fonctionnement parfait en toute situation** sur ce genre de mot rare/inventé — à ne jamais présenter comme un problème que "changer de moteur" réglerait entièrement. Le levier le plus directement pertinent pour ce cas précis n'est pas le modèle d'interprétation (LLM à sortie structurée, voir plus haut) mais le **vocabulaire personnalisé côté reconnaissance elle-même** ("boosting") — un mécanisme distinct de celui décrit plus haut dans cette section, en amont de l'interprétation, pas à sa place : - **Google Cloud Speech-to-Text** (*speech adaptation* / *phrase hints*) et **Deepgram** (*keyterm prompting*, récemment étendu à plusieurs langues) permettent de fournir au moteur une liste de mots/expressions attendus (noms de domaine ASPIC, société, agents...) pour augmenter leur probabilité de reconnaissance au moment de la décision — conceptuellement la même idée que `AGN_Variantes`, déjà validée pour les prénoms d'agents, appliquée cette fois au vocabulaire métier. - **Non disponible côté gratuit :** l'API du navigateur (`webkitSpeechRecognition`) expose bien un paramètre `grammars` prévu à l'origine pour ce genre d'usage, mais Chrome ne l'exploite pas réellement en pratique (accepté sans effet) — ce levier suppose de passer par une vraie API payante. - **Prix vérifiés le 3 septembre 2026** (susceptibles d'évoluer) : Google Cloud Speech-to-Text v2, reconnaissance standard, environ 0,016 $/minute (dégressif au volume) — seul fournisseur à documenter une option dédiée à la conversion ponctuation dictée→symbole (`enableSpokenPunctuation`), sans confirmation que le français soit couvert par cette option précise. Deepgram Nova-3 multilingue, environ 0,005 $/minute, formatage automatique ("Smart Formatting") inclus sans supplément, 200 $ de crédit d'essai gratuit — couverture française du *keyterm prompting* spécifiquement non confirmée par la documentation à ce jour. OpenAI (gpt-transcribe), environ 0,0045 $/minute en asynchrone (plus cher en flux continu), sans fonction de ponctuation dictée documentée. - **Le coût en dollars est négligeable à l'usage envisagé** (quelques dollars par mois même à un usage quotidien soutenu) — ce n'est pas ce qui doit trancher. Ce qui coûte réellement, c'est le changement d'architecture : ces API ne s'utilisent pas depuis le navigateur comme aujourd'hui (gratuit, zéro serveur) — il faudrait capturer l'audio et le faire transiter par un point d'entrée serveur détenant une clé tenue secrète, fin de la solution 100% navigateur actuelle. **Décision : épuiser d'abord la piste gratuite (dictionnaire de conversion + segmentation explicite au clic, "mode adresse" de `micro_test.js`, voir journal section 27) avant d'investir dans une API.** Pas de décision définitive sur le recours à une API — dépendra du taux d'échec réellement mesuré sur la campagne de tests que Jean-Marc prévoit de mener le 4 septembre. Si le taux reste insuffisant, Deepgram est le candidat à tester en premier (le moins cher, formatage inclus), Google Cloud restant l'option la plus directement conçue pour le problème de ponctuation dictée mais à vérifier en vrai plutôt que sur la seule doc, notamment pour la couverture du français. ## 13. L'interprétation structurée passe l'épreuve du réel, et fait émerger un nouveau besoin : séparer les actions "humaines" des actions "vocales" (4 septembre 2026) **L'hypothèse de la section 12 est validée en conditions réelles, pas seulement sur le papier.** Premier outil réel d'interprétation d'une dictée par LLM à sortie structurée (voir journal de développement, section 29, pour le détail technique — `contact_ia_interprete.php`/`contact_ia_valide.php`/`contact_ia_panel.js`, jamais d'écriture dans les vraies tables de contacts, tout passe par une table à part `ASP_PropositionsContact`). Bilan de Jean-Marc sur un premier corpus réel de 11 essais, sans ambiguïté : *"c'est vraiment super ! Les tests sont vraiment encourageants."* Deux points restent ouverts (une adresse mail mal nettoyée d'un mot d'appel et d'un accent ; une possible troncature de fin de dictée par le nouveau minuteur de silence) mais ne remettent pas en cause l'approche elle-même — ce sont des réglages fins, pas un problème de méthode. Point vérifié explicitement avec Jean-Marc et à retenir comme garde-fou de confiance dans l'outil : la détection et le classement en premier de l'action "ajouter le contact" sont une vraie décision du LLM portée par le prompt, pas un cas particulier codé en dur côté Claude. **Décision architecturale actée en cours de session, à retenir comme principe général pour toute future couche d'interprétation vocale :** cette couche doit rester un enregistreur honnête de ce qui a été réellement dit, jamais un lieu où s'invitent des règles métier. Concrètement : l'attribution d'un assistant par défaut quand aucun n'est nommé dans la dictée n'est **pas** de son ressort — cette décision reviendra à un futur traitement n8n, au moment de transformer une proposition validée en vrai post-it. Mélanger les deux aurait fait perdre la trace de ce que Jean-Marc a réellement dicté derrière une interprétation déjà "arrangée". **Nouveau besoin architectural identifié par Jean-Marc à l'usage, non conçu ni codé — à reprendre dans une prochaine session.** En listant les actions qu'un contact peut porter (envoyer une doc, proposer un tarif...), Jean-Marc a réalisé que la création du contact lui-même mérite d'être une action à part entière au même titre que les autres — mais une action à double accès : le classement la place toujours en premier, elle est bien connue du LLM vocal (qui doit la détecter et la renvoyer classée), **et** l'utilisateur humain doit pouvoir la déclencher directement depuis un menu ou un raccourci clavier, sans passer par la voix. Jean-Marc souhaite généraliser ce principe à l'ensemble des actions d'ASPIC : une séparation formelle entre les actions utilisables par l'utilisateur humain (menu/écran classique) et celles utilisables par le LLM de saisie vocale, tout en gardant les deux voies d'accès parfaitement alignées sur un même vocabulaire d'actions et un même ordre. C'est précisément le motif qui structure sa satisfaction du jour : *"ce qui me plaît c'est que je vois bien que j'arrive à suivre ma logique : des fonctionnalités accessibles via des menus et écrans de façon tout à fait classique et ces mêmes fonctionnalités accessibles par des ordres vocaux fiables donnés à des assistants !"* — une confirmation, par la pratique, du principe de double accès déjà esquissé dans la vision "bureau à l'ancienne" (section 11) : mêmes fonctionnalités, deux portes d'entrée. Rien n'est conçu ni codé sur ce point à ce stade ; voir journal de développement, section 29, pour le détail du besoin tel que formulé. **Situation acceptée comme normale, pas un défaut à corriger : une profession peut être proposée "nouvelle" plusieurs fois avant traitement.** Deux dictées distinctes du corpus ont fait remonter deux fois la même profession ("Informaticien") comme nouvelle. Jean-Marc a tranché sans hésitation : c'est acceptable tant qu'un assistant n'a pas traité le post-it — il suffira, au moment du traitement, de vérifier si la profession n'a pas déjà été créée entre l'enregistrement de la note vocale et son traitement. Pas de mécanisme de déduplication à construire à ce stade. ## 14. Le pilotage vocal comme deuxième mode de fonctionnement — consignes en langage naturel plutôt que règles programmées, et naissance du "journalier" (5-6 septembre 2026) **Origine — un blocage ancien qui refait surface autrement.** Jean-Marc a repris une réflexion mise de côté depuis la gestion des contacts : il s'était alors arrêté sur l'idée d'ajouter un menu à ribambelle d'options pour les actions possibles sur un contact, jugé indigeste (empilement d'écrans), sans trouver d'alternative à l'époque. En pratiquant ses essais de dictée (initialement destinés uniquement à valider que la retranscription était fidèle, voir journal de développement section 27/29), il s'est surpris, une fois détendu sur la technique, à vouloir donner une instruction longue et naturelle comme à une vraie assistante — exemple donné : *"ajouter aux contacts Pierre Beurel que j'ai rencontré ce midi au restaurant, qui est plombier à Lorient [...] Envoyez-lui la doc du répondeur [...] et il va falloir le suivre de près"*. Non fait, mais le seul fait d'en avoir eu l'envie a déclenché cette session de réflexion stratégique. **Hypothèse initiale, posée puis dépassée en cours d'échange.** Première piste explorée : réserver le clavier aux opérations structurantes (définir les données de base) et la voix à la "mise en musique" (passer à l'action), avec un socle d'actions atomiques (créer un contact, envoyer un doc précis) accessible par les deux voies — dans la continuité du principe de double accès déjà acté le 4 septembre (section 13). Cette hypothèse a été explicitement corrigée par Jean-Marc sur un point : même une action atomique n'a pas sa place sur l'écran du classeur de contacts. **Le classeur de contacts n'est, et ne sera jamais, un outil d'action — seulement un répertoire et un historique.** Jean-Marc s'appuie sur la métaphore du bureau à l'ancienne (section 11) pour trancher : ouvrir le classeur, le feuilleter, ajouter une fiche, en déchirer une — c'est la vie du classeur lui-même, pas une action métier. Voir une fiche et juger qu'il faut agir dessus (envoyer une doc, programmer un suivi) ne se traite jamais en restant dans le classeur — dans la vraie vie, ça se note sur un bout de papier, ça se vérifie éventuellement sur des profils similaires, ça se discute avec un collaborateur. Conséquence actée : aucune action métier, même simple, ne sera déclenchable depuis la fiche contact elle-même ; agir passe entièrement par le canal d'instruction en langage naturel (voix ou texte), la consultation reste entièrement séparée. **Le vrai changement de paradigme : des consignes en langage naturel, pas des règles programmées par écrans.** Jean-Marc a explicitement rejeté l'idée de construire les règles de fonctionnement en remplissant des écrans à embranchements ("comme on programmait des chatbots autrefois... qui finissait toujours par mener à un mur"). À la place : une "ribambelle de consignes" en phrases simples, à la manière dont un dirigeant forme son personnel — exemples donnés tels quels par Jean-Marc : *"les documentations sont envoyées par mail"*, *"nous avons 3 documentations : générale, répondeur, CRM"*, *"toutes nos données sont hébergées en Europe, on est RGPD"*, *"en règle générale on relance le contact après l'envoi d'une documentation au bout d'une semaine"*. Aucune catégorisation a priori de ces phrases (fait, règle de comportement, contrainte réglementaire) n'est nécessaire ni souhaitée — cohérent avec le rejet des écrans à embranchements, et laissé à la capacité de compréhension du LLM tant que la liste reste d'une taille raisonnable à tenir en contexte (le jour où elle grossit trop, la question d'une recherche plutôt qu'une inclusion intégrale se reposera, comme déjà anticipé pour le RAG en section 12 — non traité maintenant). **Cadre revendiqué explicitement par Jean-Marc : la démarche qualité PDCA (plan-do-check-act), en opposition assumée à une tendance qu'il s'attribue à lui-même/à une culture française** ("qui pense faire tout de suite parfait et [...] s'attaque à des séries d'Everest" plutôt que de monter les marches une à une). Il relie cette prise de conscience à la discipline déjà appliquée depuis le début du projet (constituer un corpus de dictées réelles avant de concevoir des règles d'interprétation, voir section 12) — pas une nouveauté de méthode, mais une explicitation du principe déjà à l'œuvre. **Processus en quatre phases, proposé par Jean-Marc pour l'interprétation d'une instruction :** 1. **Traduction globale** — la dictée (ou une saisie texte dans une fenêtre dédiée, les deux canaux étant désormais vus comme équivalents, la voix n'étant qu'une des deux portes d'entrée du même pipeline) est analysée pour produire une reformulation fidèle de la demande. Cette phase reste l'enregistreur honnête déjà posé comme principe le 4 septembre (section 13) — aucune règle métier n'y entre. 2. **Vérification de la compréhension** de la demande par rapport aux consignes établies, puis transmission à l'assistant concerné (matérialisée par la création d'un post-it — détail d'interface, non structurant). 3. **Traitement par l'IA et proposition de retour** — un retour n'est pas systématique : une suppression de fiche sans enjeu peut ne rien nécessiter, sauf si, par exemple, un devis est en cours. Ce point généralise le principe déjà posé le 3 septembre (section 12) selon lequel le statut "à valider" est une propriété portée par l'action et non un seuil de confiance global : cette propriété devient elle-même une décision calculée par les consignes selon le contexte réel, plutôt qu'une caractéristique fixée une fois pour toutes par type d'action. 4. **Validation ou abandon** des actions proposées par Jean-Marc (ou plus tard un collaborateur) — un abandon pouvant, à terme, entraîner une évolution des consignes elles-mêmes. **Acceptation explicite que l'assistant développe "sa propre réflexion" et propose au-delà du cadre strictement anticipé.** Jean-Marc assume pleinement ce point, en s'appuyant sur une analogie de management : un dirigeant autoritaire qui a toujours raison bride l'initiative de son personnel, quand un dirigeant plus ouvert (sans tout accepter) permet à la structure de capitaliser et de progresser. Il y voit l'usage réellement différenciant de l'IA pour son futur agence, et un argument commercial potentiel (*"Adoptez l'outil qui va apprendre avec vous !"*), en contraste direct avec des outils lourds et figés (l'expérience SAP de sa compagne, section 12). **Nuance apportée par Claude et retenue comme point de vigilance pour la crédibilité de cet argument commercial :** contrairement à un employé humain, une IA n'apprend spontanément de rien d'un appel à l'autre — la capitalisation ne sera réelle que parce que le mécanisme pour la capturer (consignes écrites, journalier conservé, boucle validation/abandon) est construit explicitement à cet effet. L'argument de vente doit donc s'appuyer sur cette discipline explicite plutôt que sur une "magie" de l'IA que rien ne garantirait techniquement. **Décision actée : naissance du "journalier".** Un des classeurs du bureau à l'ancienne (section 11) portera ce nom et consignera les actions réalisées par les assistants (et possiblement l'utilisateur humain — périmètre exact non encore tranché) par demi-journée, avec leurs résultats : un outil d'aide à la décision pour le dirigeant. Terme choisi par Jean-Marc en toute fin d'échange pour éviter la confusion avec "le journal de développement" (ce document technique tenu avec Claude) — les deux journaux répondant, comme Jean-Marc l'a lui-même relevé, à un besoin structurellement identique : le journal de développement permet à Claude de repartir à froid d'une session à l'autre sans tout redemander ; le journalier jouera le même rôle de mémoire relue, cette fois pour les assistants d'ASPIC entre leurs propres interventions. Ce besoin recoupe celui déjà identifié le 4 septembre dans le journal de développement (section "reste à faire" : écran journalier de trace des réalisations humain + assistants), pour lequel une bonne part de la donnée existe déjà (`TDL_RealDate`/`TDL_RealUser`/`TDL_RealText` dans `ASP_ToDoList`). **Prolongement : classification des journaliers par domaine, pour une alimentation ciblée et éventuellement silencieuse de l'IA.** Jean-Marc propose de classer les entrées du journalier par domaine (marketing, financier...) afin que la capitalisation sur l'historique soit réelle et systématique, plutôt que ponctuelle sur demande explicite (à l'image de ce qui se fait aujourd'hui pour une section du journal de développement — "demander sa lecture"). Rapprochement suggéré par Claude, non tranché : réutiliser `AGN_Fonction` (déjà utilisé pour classer chaque assistant par domaine) comme classification des journaliers plutôt que de construire une seconde taxonomie à maintenir en parallèle. **Garde-fou retenu par Jean-Marc comme future consigne de fonctionnement à part entière :** toute proposition de l'IA motivée par un antécédent du journalier doit citer cet antécédent — pour que l'alimentation silencieuse de l'historique n'érode pas la visibilité sur laquelle repose tout le mécanisme de validation/abandon décrit plus haut. **Idée complémentaire, non conçue :** inciter l'utilisateur à noter/apprécier le retour d'une action réalisée, pour nourrir le journalier — sans nouveau mécanisme d'interface nécessaire, cette appréciation pouvant emprunter le même canal en langage naturel que les instructions elles-mêmes (une phrase de plus, que la phase 1 du pipeline classerait comme un retour d'expérience à verser au journalier plutôt que comme un ordre à exécuter). **Statut : orientation actée dans ses grandes lignes, aucun développement engagé.** Rupture assumée avec l'idée initiale d'un simple double accès clavier/voix aux mêmes fonctionnalités (section 13) : le clavier structure les données et le vocabulaire, la voix compose les actions, et les consignes qui gouvernent cette composition sont elles-mêmes écrites en langage naturel plutôt que programmées. Points laissés ouverts pour une prochaine session : - Le mécanisme concret d'évolution des consignes : modification uniquement par Jean-Marc après un abandon, ou un assistant pouvant proposer une consigne candidate après avoir constaté une répétition de refus — écho possible du principe déjà appliqué au code d'ASPIC ("généraliser à partir de 3 répétitions concrètes constatées", section 6). - Un corpus de consignes commun aux quatre assistants, ou un livret propre à chacun selon son `AGN_Fonction`. - Le périmètre exact du journalier (actions des assistants seulement, ou humain + assistants comme envisagé initialement le 4 septembre pour l'écran journalier du journal de développement). - La fréquence d'alimentation du journalier par n8n (par demi-journée évoquée par Jean-Marc, ou calée sur le rythme réel de l'agent de veille dont le réglage reste, comme noté en section 12, à choisir plus tard) — non encore décidée par Jean-Marc au 6 septembre. ## 15. Sortir du code en dur : règles et consignes comme mécanisme générique, premier cas construit sur la fiche Contacts (6 septembre 2026) **Origine — le prolongement naturel de la session de réflexion du matin même.** Dans la continuité directe de la section 14 (le pilotage vocal comme deuxième mode de fonctionnement, consignes en langage naturel plutôt que règles programmées), Jean-Marc a voulu, le soir du même jour, poser une première brique concrète et volontairement modeste de cette philosophie — pas encore le pipeline vocal à quatre phases de la section 14, mais son fondement le plus basique : une fiche (Contacts, en création/modification) dont le comportement de validation et de mise en forme n'est plus écrit dans le code, mais lu dans des données. **La distinction posée en ouverture de session : règles vs consignes.** Une **règle** est intrinsèque à l'application, non modifiable par l'utilisateur, parfois visible et parfois totalement transparente pour lui (ex. un contrôle d'intégrité que Jean-Marc seul déciderait d'activer). Une **consigne** est éditable par l'utilisateur, en langage naturel dans son intitulé, à l'image d'une instruction donnée à une véritable assistante — ce que Jean-Marc a nommé, en cours de session, "Mathilda" pour parler concrètement de cette couche. Deux natures pour une consigne : **Traitement** (transformation silencieuse d'une valeur, ex. mise en majuscules) et **Test** (validation, avec un message d'erreur si elle échoue). Cette distinction règles/consignes, et celle Traitement/Test, sont directement héritées de la réflexion du matin (section 14) mais franchissent ici, pour la première fois, le seuil du code réel. **Le principe non négociable, formulé sans ambiguïté par Jean-Marc après une première tentative manquée de Claude (voir plus bas) : "sortir du code en dur".** L'objectif explicite n'était pas de coder telle ou telle validation, aussi propre soit-elle, mais de construire un **moteur générique** qui lit deux tables (le catalogue de fonctions disponibles, et les consignes actives qui s'appuient dessus) et qui exécute ce qu'il y trouve — de sorte qu'ajouter, modifier ou désactiver une consigne change le comportement réel de l'application **sans qu'aucune ligne de code ne soit retouchée**, sauf dans deux cas seulement assumés comme limites naturelles du système : l'écriture d'une fonction réellement nouvelle dans le catalogue, ou la correction d'un bug. Dans les mots de Jean-Marc, précisant ce qu'il ne demandait pas : *"Je n'ai aucun doute sur la capacité à programmer les tests et fonctions que tu as mis en place. Ce n'est pas cela que je souhaite tester, c'est bien toute la mécanique [...] : brancher des consignes, des règles sur la mise à jour des contacts [...] en sortant du code en dur !"* **Un détour instructif, corrigé en cours de route.** Face à la première demande de Jean-Marc (rendre le Nom obligatoire, le mettre en majuscules), Claude a d'abord câblé ces deux comportements directement dans `contacts.php`, en se disant que le cas concret viendrait avant la généralisation. Erreur de lecture du besoin, corrigée fermement par Jean-Marc : ce n'était pas la complexité de la règle qui était en jeu, mais l'endroit où elle devait vivre. Reconstruction immédiate autour d'un moteur générique unique lisant les deux tables à l'exécution, sans plus aucune référence à un champ ou une consigne précise dans le code (voir journal de développement, section 30, pour le détail technique). Ce détour, bien que corrigé rapidement, mérite d'être consigné ici : il illustre concrètement la différence entre "avoir compris l'objectif en théorie" et "construire le bon niveau d'abstraction du premier coup" — un risque qui se représentera à chaque nouvelle brique de cette philosophie plus large. **Un arbitrage assumé : la robustesse plutôt que le temps réel.** Une fois le moteur générique posé, restait la question du moment d'exécution : au clavier, au fil de la saisie (retour immédiat, "Saisie"), ou seulement à l'enregistrement ("Validation"). Jean-Marc, dépourvu selon ses propres mots de la compétence pour juger du coût réel d'un contrôle en temps réel, a choisi de trancher sur le critère qui compte le plus pour lui à ce stade du projet plutôt que sur l'exhaustivité fonctionnelle : *"je cherche aussi à ce que l'exécution soit fluide et que le code ne soit pas propice à des plantages"*. Décision : abandonner, pour cette première version du moteur, toute distinction Saisie/Validation et toute réaction en temps réel — une consigne active s'applique uniquement à l'enregistrement, quel que soit son moment déclaré en base. Ce choix a eu un effet inattendu et bienvenu : en retirant l'ancien contrôle client codé en dur, il a révélé un bug préexistant et jusque-là invisible (le message d'erreur affiché à l'écran était toujours générique, jamais celui réellement renvoyé par le serveur) — une illustration concrète du principe déjà éprouvé sur ce projet : simplifier expose parfois des défauts que la complexité précédente masquait, plutôt que d'en créer de nouveaux. **L'enseignement retenu pour l'avenir, au-delà du cas des contacts : mécanisme générique et données propres à un client ne doivent jamais se mélanger.** En discutant de l'extension possible du catalogue de fonctions à des cas plus élaborés (ex. une liste de préfixes de codes postaux propre à une zone géographique), le principe suivant a été posé comme garde-fou pour la suite : le catalogue de fonctions (`ASP_Fonctions`) ne doit contenir que des primitives **génériques et paramétrables** (ex. "la valeur appartient à telle liste"), jamais une valeur métier figée pour un client donné — celle-ci doit toujours vivre comme une donnée de consigne (`CNS_Parametres`), jamais comme du code nouveau. Ce point prend une importance particulière à la lumière du modèle SaaS envisagé pour ASPIC (section 5) : le jour où plusieurs clients partageront le même catalogue de fonctions, ce catalogue devra rester strictement neutre vis-à-vis de chacun d'eux — toute valeur propre à un client doit résider dans ses propres consignes, jamais s'infiltrer dans le mécanisme commun. **Validation par la pratique, sans qu'aucun code ne soit retouché après livraison.** Une fois le moteur et le catalogue de premières fonctions (mise en majuscule, non-vide, première lettre en majuscule) livrés, Jean-Marc a lui-même ajouté deux nouvelles consignes en base (non-vide sur le Prénom, puis sur la Ville) — comportement immédiatement actif, aucun fichier applicatif retouché. Conclusion de Jean-Marc, dans ses mots : *"On peut dire qu'on n'est pas mauvais !"* — première preuve concrète, à petite échelle, que la philosophie de la section 14 (des consignes plutôt que des écrans à embranchements) est réalisable technique­ment, pas seulement séduisante sur le papier. **Une extension entrevue mais explicitement mise de côté pour ce soir : l'appel à l'IA au sein même d'une consigne.** Jean-Marc a proposé, en fin de session, une consigne bien plus élaborée que celles construites jusqu'ici : si une ville est saisie sans code postal, aller chercher ce code postal via un appel à l'IA. Contrairement aux consignes du soir (Traitement pur ou Test pur, réponse immédiate et locale), ce cas suppose un contrat de retour plus riche (le résultat peut être silencieux, réclamer une clarification, ou poser une question), une latence et un risque d'échec réseau inédits pour ce mécanisme. Claude a recommandé de ne pas la traiter comme un simple ajout au catalogue existant, mais comme un chantier à part entière justifiant une session dédiée — recommandation implicitement acceptée par Jean-Marc, qui a préféré clore la soirée plutôt que de se lancer dans cette extension à une heure tardive. **Trois pistes proposées par Jean-Marc pour les prochaines sessions, actées ici pour mémoire :** 1. Concevoir des consignes plus élaborées faisant réellement appel à l'IA (le cas du code postal ci-dessus en étant le premier exemple concret) — préalable : définir le nouveau contrat de retour évoqué plus haut. 2. Commencer à construire un écran de gestion des consignes pour le "boss" (Jean-Marc, puis un futur client), en remplacement de la saisie SQL directe utilisée ce soir — Claude a suggéré de séquencer cet écran **après** la stabilisation du contrat de retour enrichi du point 1, pour ne pas le concevoir deux fois. 3. Réfléchir à un **catalogue restreint et curaté** de consignes et de fonctions avancées, à proposer aux futurs clients de l'agence — Jean-Marc a été explicite sur le fait qu'il n'envisage pas d'ouvrir à ses futurs utilisateurs une création libre de consignes avancées "de A à Z" ; il y voit au contraire un argument commercial pour de futures mises à jour payantes ("Possibilité de nouvelles consignes pour vos assistants"). Ce point rejoint directement la distinction actée plus haut entre mécanisme générique (partagé, neutre) et catalogue de fonctions (à curater soigneusement, puisqu'il devient potentiellement un produit en soi). **Statut : premier cas concret bâti et validé, philosophie plus large confirmée par la pratique.** Le moteur générique de consignes existe, fonctionne, et a déjà changé de comportement une fois sans code — scellant, à l'échelle d'un cas modeste, l'intuition posée le matin même en section 14. Trois directions ouvertes pour la suite (consignes IA, écran de gestion, catalogue commercial), aucune engagée à ce stade au-delà de la discussion. ## 16. Lier une session à l'ordinateur de Jean-Marc — vers la fin des allers-retours de fichiers, et une question de fond sur la visibilité du code (7 septembre 2026) **Origine — une question posée en marge, pas un chantier planifié.** Jean-Marc a repéré, dans des mails d'Anthropic, l'existence d'une fonctionnalité permettant de donner à Claude un accès en lecture/écriture direct à un ou plusieurs répertoires de son poste, et a demandé confirmation. Vérification faite (documentation officielle Anthropic) : la fonctionnalité existe bien — une session peut être liée à un ordinateur via l'application desktop Claude ("Link to this computer"), avec ensuite un octroi d'accès dossier par dossier (jamais le disque entier d'un bloc), strictement à la demande de l'utilisateur. **Le vrai motif, une fois creusé : soulager une friction bien réelle du circuit de livraison actuel.** Le mode de fonctionnement en place depuis le début du projet (fichiers envoyés en pièce jointe de conversation, à télécharger, parfois renommés en double par le navigateur, puis copiés/renommés à la main dans le dossier de transfert SFTP de Jean-Marc) fonctionne mais coûte de l'attention à chaque fichier, avec un risque concret d'erreur relevé par Jean-Marc lui-même : *"Parfois, notamment quand nos échanges sont intenses, je loupe un téléchargement et je suis aux fraises."* Deux irritants précis identifiés et confirmés techniquement réglés par ce mécanisme : - Le contournement `.js.txt` pour les fichiers JavaScript (nécessaire jusqu'ici uniquement parce que la livraison passait par le téléchargement navigateur, peu compatible avec ce type de fichier) — disparaît entièrement avec une écriture directe sur disque. - Le renommage automatique en doublon (`toto_47.php` au lieu d'écraser `toto.php`) — même cause, même remède : en écrivant directement dans le dossier cible, le fichier livré porte son nom final et écrase silencieusement l'ancien, sans étape de tri manuel. **Mécanique vérifiée dans la documentation officielle, à retenir pour la mise en œuvre :** - Une fois un dossier accordé pour une tâche/projet lié à un ordinateur, l'autorisation est retenue d'une session à l'autre — pas besoin de la redonner à chaque ouverture. Condition permanente cependant : l'application desktop Claude doit être ouverte et la machine joignable au moment où une session cloud veut effectivement toucher aux fichiers ; application fermée, le pont est simplement indisponible (pas une erreur, pas une perte de la permission). - Concernant le NAS Synology de Jean-Marc, accédé sous Windows via une adresse IP locale : un partage réseau **mappé sur une lettre de lecteur** (ex. `Z:\`) est pris en charge par le sélecteur de dossier ; un chemin UNC brut (`\\192.168.x.x\partage`) ne l'est pas directement. Jean-Marc a confirmé que son NAS est déjà monté par lettre — pas de point de blocage de ce côté. Seule variabilité relevée par Jean-Marc lui-même : le NAS peut se mettre en veille en cas d'inactivité prolongée et mettre un instant à répondre, mais reste actif par construction lorsqu'il est à son bureau. **Décision : Jean-Marc prépare un répertoire réseau dédié au développement d'ASPIC (`Développement`), avec une arborescence calquée sur celle du VPS**, pour que déposer un fichier reçu de Claude s'y réduise à un simple report dans le bon sous-dossier, sans réflexion supplémentaire. Ce pont ne remplace à aucun moment la gestion du dépôt GitHub, que Jean-Marc continue d'opérer intégralement lui-même — **précision explicite de sa part : la clé GitHub ne sera pas donnée à Claude dans le cadre de cette organisation**, ce qui clôt d'un coup la question du blocage de push déjà bien documentée (journal de développement, section 23) : le sujet devient sans objet plutôt que contourné. **Question de fond soulevée en cours de discussion : la documentation soignée du code a un revers.** Jean-Marc a exprimé une satisfaction ancienne et jamais obtenue de ses développeurs précédents — voir le code commenté avec soin, but qu'il avait longtemps réclamé sans l'obtenir — tout en identifiant lui-même la contrepartie : plus un fichier est documenté, plus il informe un œil indiscret qui y aurait accès (un visiteur via "Afficher le code source" sur les fichiers HTML/JS réellement exposés au navigateur ; ou, dans une hypothèse plus lointaine, un client final ayant lui-même accès aux fichiers de son propre hébergement, si le modèle (a) de la section 5 — éditeur déployé chez le client — était un jour retenu pour un projet one-shot). Rappel de contexte déjà posé et confirmé toujours valable : les fichiers PHP ne sont eux-mêmes jamais transmis au navigateur (exécution côté serveur), donc leurs commentaires ne sont, par construction, jamais visibles d'un simple visiteur — le risque concret porte avant tout sur les fichiers HTML/JS, et plus largement sur toute situation où quelqu'un obtiendrait un accès direct aux fichiers sources eux-mêmes plutôt qu'au seul rendu navigateur. **Solution retenue : une version "exploitation" du code, générée à la demande, jamais systématiquement.** Plutôt que de renoncer à la qualité de documentation acquise sur ce projet (dont la valeur pour la continuité du travail avec Claude reste entière, voir section 2), Jean-Marc a proposé de pouvoir demander, ponctuellement et une fois l'application arrivée à un certain point de maturité, une copie des sources débarrassée de tout commentaire — à déployer à la place de la version pleinement documentée, celle-ci restant la référence de travail. Décision actée : construire cet utilitaire (retrait de commentaires par analyse syntaxique réelle du langage — pas une simple recherche/remplacement de texte, qui risquerait de corrompre une chaîne de caractères contenant `//` ou un délimiteur de commentaire), à ranger dans un sous-dossier `Exploitation` du futur répertoire réseau, en miroir de `Développement`. Portée explicitement limitée, pour ne pas se tromper sur ce que ça protège réellement : un simple retrait de commentaires (le code, sa mise en forme et ses noms de variables restent identiques, ce n'est pas une minification ni un chantier d'obscurcissement) réduit la fuite d'information gratuite vers un œil curieux, mais ne constitue pas une vraie protection contre un acteur déterminé — cohérent avec le constat déjà posé en section 5 (aucune protection réelle n'existe pour du PHP/JS vanilla livré tel quel). **Confrontation au réel : la demande d'accès a buté sur un bug documenté de Windows, pas sur une erreur de configuration.** Une fois le répertoire préparé côté NAS, la demande d'octroi pour `G:\01. Version 1\000. Développement` a été refusée par le mécanisme de sélection de dossier, avec un message ne pointant vers aucune cause côté Jean-Marc ("Ask the user to connect the folder they want using the folder picker on their device, or pick a different folder"). Plutôt que de proposer une manipulation au hasard, recherche faite : il s'agit d'un bug Windows réel et déjà documenté (plusieurs tickets ouverts sur le dépôt public `anthropics/claude-code`, dont #38468, #24927, #24964) — le sélecteur de dossier de l'application desktop rejette actuellement, sous Windows, tout dossier situé hors du profil utilisateur (`C:\Users\\`), y compris un lecteur réseau mappé sur une lettre pourtant explicitement pris en charge par la documentation officielle ; les jonctions/liens symboliques ne contournent pas le problème, la résolution du chemin réel bloquant également ce chemin de traverse. Statut du bug à la date de cette session : non résolu, ticket fermé comme doublon sans correctif. Une tentative parallèle, créer un nouveau projet directement à partir d'un dossier pour voir si un autre point d'entrée existait, n'a fait apparaître aucune option de partage de fichiers. Conclusion honnête tirée de cet épisode, formulée par Jean-Marc lui-même et retenue comme point de vigilance pour la suite des échanges : une fonctionnalité présentée comme possible en théorie peut ne pas l'être réellement au moment de passer à l'action — une raison de plus, au-delà de ce chantier précis, de rester prudent sur ce qu'affirme Claude tant que ce n'est pas vérifié en conditions réelles. **Une seule alternative restait disponible — un dossier sous `C:\` — et Jean-Marc l'a refusée, pour deux raisons distinctes et toutes deux jugées valables.** La première, posée sous forme d'image par Jean-Marc lui-même : donner l'accès à une pièce, même partiel, se choisit d'abord sur la pièce la moins sensible — entre un coffre-fort à espace réduit et une pièce d'armoires de rangement, l'accès s'ouvre sur la seconde, jamais sur le premier ; le disque `C:` héberge le système et le profil de l'utilisateur, il n'a pas vocation à devenir un point d'échange de fichiers de développement, quel que soit le soin apporté à la restriction du dossier précis accordé. La seconde raison, plus concrète et finalement décisive : une expérience vécue par Jean-Marc, un disque `C:` d'un poste stratégique arrivé à saturation à un moment où personne n'avait le temps de s'en occuper, avec pertes de données à la clé. Le volume actuel d'ASPIC sur le réseau (un peu plus de 65 Mo) est dérisoire au regard des quelque 300 Go encore libres sur le NVMe de son poste — mais Jean-Marc raisonne sur la durée du projet et sur la tendance (de nouvelles applications viendront occuper `C:` au fil du temps), pas sur l'instantané d'aujourd'hui. Claude a reconnu ce raisonnement comme fondé plutôt que d'insister sur la marge disponible dans l'immédiat. **Décision finale, actée par Jean-Marc : abandon complet de l'accès direct au disque, retour à l'organisation existante.** Dans ses propres mots : *"restons zen, oublions cette idée d'accéder directement à une partie de mon disque autre que C: et restons sur l'organisation actuelle."* Le circuit de livraison redevient donc, sans changement, celui décrit en ouverture de cette section (téléchargement depuis la conversation, contournement `.js.txt` pour le JavaScript, renommage manuel `toto_nn.php` → `toto.php`) — les deux irritants identifiés en début de section restent entiers, faute d'un mécanisme technique aujourd'hui utilisable pour les résoudre. Effet positif retenu malgré tout par Jean-Marc : l'occasion de cette exploration l'a poussé à réorganiser son stockage réseau, une remise en ordre qu'il envisageait depuis longtemps et qu'il n'aurait pas faite sans ce prétexte. **Fil ouvert et volontairement laissé de côté : un connecteur GitHub repéré au compte de Jean-Marc.** En cherchant le sélecteur de dossier, Jean-Marc a découvert qu'une intégration GitHub était déjà activée au niveau de son compte Anthropic, sans qu'elle soit pour autant utilisable dans la conversation en cours (les outils disponibles n'en portaient aucune trace au moment de la vérification). Jean-Marc a choisi de ne pas creuser ce point maintenant ("je vais voir plus tard pour cette connexion GitHub"), sans lien avec la décision de ne pas donner sa clé GitHub à Claude pour l'organisation de fichiers locale (section précédente), qui reste, elle, définitivement actée et non remise en cause par cette découverte. **L'utilitaire de retrait de commentaires reste construit et disponible, indépendamment de l'issue de ce chantier.** Le renoncement à l'accès disque direct ne remet rien en cause côté "version exploitation" : les deux scripts (un pour le PHP par analyse syntaxique réelle via `token_get_all()`, un pour le HTML/JS via `terser` en configuration retrait-de-commentaires seul, sans compression ni renommage) ont été construits et validés ce même jour sur des fichiers réels du projet (syntaxe vérifiée après traitement, contenu fonctionnel inchangé) — prêts à resservir le jour où Jean-Marc en fera la demande, quel que soit le circuit de livraison alors en place pour les faire parvenir. **Statut en fin d'échange : chantier clos, pas suspendu.** Contrairement à la formulation précédente de ce paragraphe (qui envisageait deux chantiers parallèles en cours), l'accès direct au disque de Jean-Marc est abandonné, pas différé — à ne pas rouvrir sans qu'il en fasse à nouveau la demande, par exemple si Anthropic corrige un jour le bug identifié ci-dessus. Le circuit de livraison par téléchargement reste donc la référence pour la suite du projet. Le numéro de version (partie ``) n'a pas été avancé à l'occasion de cette section, conformément à la décision initiale de Jean-Marc — la nouvelle organisation qui devait servir de test grandeur réelle pour ce déclenchement n'ayant finalement pas vu le jour, ce report reste sans objet pour l'instant plutôt que remis à plus tard. ## 17. Sortir du code en dur : règles et consignes comme mécanisme générique [Évolutions majeures] (7 septembre 2026) **Origine.** Dès le lendemain de la première mise en œuvre du moteur générique (section 15), Jean-Marc a engagé exactement le chantier que cette section-là avait explicitement mis de côté comme méritant "une session dédiée" plutôt qu'un simple ajout au catalogue : une consigne capable d'appeler l'IA en cours de traitement (retrouver le code postal d'une ville saisie sans code postal), avec tout ce que ça implique de nouveau pour le moteur — coût réseau à ne jamais gaspiller, traçabilité de qui a réellement agi, et honnêteté du retour utilisateur en cas d'échec. Suffisamment substantiel pour justifier une nouvelle section plutôt qu'un addendum à la section 15. **Le prix de la vitesse : hiérarchiser pour ne jamais payer un appel IA en pure perte.** Premier essai réel de Jean-Marc sur le nouveau moteur : une soumission vouée à échouer sur un Test (ex. champ obligatoire vide) déclenchait quand même, avant l'échec, un Traitement coûteux faisant appel à l'IA — appel réseau gaspillé, et aucune trace n'en subsistait puisque l'enregistrement entier était de toute façon rejeté ensuite. Diagnostic de Jean-Marc, structurel plutôt qu'un simple correctif ponctuel : *"il faut qu'on hiérarchise les traitements : d'abord les traitements de cohérence, après les traitements par IA."* Plutôt que de traiter ce cas précis à part, l'ordre d'exécution du moteur lui-même a été restructuré en trois phases séquentielles, distinguées par un seul attribut déjà présent dans le catalogue (`FON_VisuelAttenteIA`, voir plus bas) : d'abord les Traitements sans appel IA, puis tous les Tests (le premier échec arrête tout avant d'atteindre la moindre étape IA), et seulement une fois tous les Tests passés, les Traitements IA. Une seule distinction générique déjà présente sert donc à la fois de commande d'affichage (le badge, ci-dessous) et de garde-fou de coût — aucune nouvelle colonne, aucun cas particulier par fonction. **Un badge générique pour ne jamais laisser l'utilisateur dans le flou pendant un appel réseau.** Un Traitement pouvant désormais réellement contacter un service externe avant la fin d'un enregistrement, Jean-Marc a voulu un retour visuel plutôt qu'un silence pendant l'attente. Nouvel endpoint `consignes_apercu.php`, et une convention de fonction jumelle : tout Traitement marqué `FON_VisuelAttenteIA='O'` doit être accompagné d'une fonction `_seraitDeclenchee(array $valeurs): bool` — pure, sans appel réseau — répondant à "ce traitement se déclencherait-il réellement sur ces valeurs", utilisée pour décider, avant même de tenter l'enregistrement, s'il faut afficher un badge de chargement générique. Volontairement générique plutôt que personnalisé par agent/couleur : Jean-Marc a explicitement écarté un badge coloré par agent (*"si un jour un traitement fait appel à plusieurs agents à la suite, il ne faudrait pas que l'écran se transforme en sapin de Noël"*) et son affichage systématique à chaque enregistrement, IA ou non (*"l'utilisateur pourrait s'affoler sur le coût systématique d'une insertion client"*). Plusieurs allers-retours sur la taille du badge (130 → 50 → 25 → retour à 65px) avant validation — un détail purement cosmétique, mais qui a nécessité de regarder le rendu réel (Playwright) plutôt que de deviner une valeur en pixels dans l'abstrait. **Traçabilité : qui a réellement agi, jamais un nom inventé.** Premier jet de Claude sur la journalisation d'une action IA : un prénom d'agent codé en dur ("Mat"). Repéré et corrigé après une question directe de Jean-Marc (*"d'où sors-tu le diminutif Mat ?"*) — Claude a reconnu l'avoir inventé, sans source. Décision retenue : le nom de l'agent journalisé dans une réalisation vient désormais uniquement de `CNS_Agent` (la consigne elle-même), jamais d'une valeur proposée par la fonction de traitement — même principe que celui déjà en place pour un agent en échec de Test. Dans le prolongement direct, Jean-Marc a voulu qu'un enregistrement de réalisation garde le prénom affiché de qui a agi (humain ou IA) sans avoir besoin de le recalculer plus tard : *"si on stocke le prénom de l'utilisateur d'un côté et le prénom de l'agent en dur on est cool."* Une première proposition de Claude (jointure `ASP_Users` recalculée à la lecture) a été explicitement écartée par Jean-Marc, sur deux arguments distincts : la complexité de la requête (*"Ta requête SQL risque d'être compliquée non ?"*) et surtout la portabilité multi-bases du projet (*"comment vas-tu faire pour les agents qui sont dans une autre base ?"*, en écho direct à l'architecture MIRADOR, section 8). Solution retenue : un instantané écrit une seule fois à la création de la réalisation (`REA_NomAffiche`) — côté humain via `$_SESSION['USR_Prenom']` fixé une fois pour toutes à la connexion, côté IA via le nom déjà connu de l'agent — zéro requête supplémentaire à la lecture, zéro risque de base croisée. **Un renommage anodin en apparence, une leçon retenue.** À l'occasion de cette traçabilité, Jean-Marc a rappelé l'existence d'une table `ASP_Agents` déjà en place (utilisée pour le pilotage vocal, sections 11-12) et proposé d'harmoniser sa colonne `AGN_Nom` en `AGN_Prenom`, cohérent avec `USR_Prenom`. Claude a validé le renommage en affirmant "aucun impact côté code" — sans avoir grep le nom de colonne dans l'ensemble des fichiers existants. Conséquence concrète et immédiate pour Jean-Marc : *"j'ai un message qui me dit que la liste des agents n'est pas disponible !"* — cinq fichiers pré-existants (`agents.php`, `micro.js`, `contact_ia_panel.js`, `contact_ia_interprete.php`, `agent_notes.php`) référençaient encore `AGN_Nom`, cassant au passage le pilotage vocal. Réaction de Jean-Marc, sans dramatisation : *"Classique à ce stade du développement."* Leçon explicitement actée par Claude comme réflexe permanent pour la suite du projet, au-delà de ce seul incident : **grep systématiquement le nom d'une colonne dans tout le code avant d'affirmer "aucun impact" sur un changement de schéma, même quand ça semble anodin** — un changement de schéma n'est jamais gratuit à évaluer sans preuve, quelle que soit l'ancienneté ou la banalité apparente de la colonne touchée. **Le premier vrai "contrat de retour enrichi" pour une consigne à appel IA — plus modeste que prévu, mais réel.** La section 15 anticipait un contrat à trois issues (silencieux / besoin de précision / question à poser) pour ce type de consigne, jugé trop tôt à concevoir dans l'abstrait. Ce qui a réellement été construit ce soir est un premier incrément volontairement plus modeste : réutilisation du mécanisme de clé réservée déjà existant (`_realisation`, jamais écrite dans `$data`, extraite par le moteur) et ajout d'une seconde clé du même type, `_avertissement` — une simple chaîne, affichée immédiatement à l'écran, sans que le front-end sache jamais d'où elle vient (mécanisme générique, pas un cas particulier "code postal" câblé côté écran). `consigne_completer_code_postal`, quand elle ne peut rien déduire d'exploitable pour une ville ambiguë ou inconnue (le cas Paris, découpée en arrondissements, sans code postal unique), laisse désormais une trace honnête dans tous les cas : une `_realisation` est journalisée que l'appel ait réussi ou échoué (Jean-Marc avait explicitement signalé l'anomalie inverse : *"il y a un appel fait à l'IA et pas de trace dans les réalisations, ce qui n'est pas normal"*), et `_avertissement` fait en plus remonter l'échec à l'utilisateur sans délai. À noter honnêtement : ce n'est pas encore le contrat à trois issues complet envisagé en section 15, seulement un succès silencieux ou un échec avec avertissement — un choix délibéré de construire la plus petite chose réelle plutôt que l'abstraction complète par anticipation, dans la continuité de la discipline déjà appliquée sur ce projet ("généraliser à partir de 3 répétitions concrètes constatées", section 6). **D'un toast qui disparaît à un message qui exige une décision.** Trois allers-retours d'affinage dans la soirée sur le seul retour visuel de cet avertissement, chacun corrigeant un défaut concret repéré par l'usage réel : rouge et centré comme un vrai message d'erreur plutôt qu'un toast neutre en bas d'écran ; le panneau reste en mode édition au lieu de repasser silencieusement en mode vue (*"tu peux l'afficher en rouge et centré et rester dessus comme un message d'erreur"*) ; puis, une fois testé, le message disparaissait encore trop vite et la fiche restait visuellement "non validée" aux yeux de Jean-Marc malgré un enregistrement réellement réussi en base — solution retenue : un message réellement bloquant, sans disparition automatique, avec un unique bouton "Valider" dont le clic est la seule chose qui referme le message et fait alors passer l'affichage en mode vue. Dans les mots de Jean-Marc : *"je souhaite que le message s'affiche et reste en place [...] avec une instruction claire 'Saisissez le code postal vous-même' et que lorsque l'utilisateur clique, la fiche soit validée."* Point de conception à retenir : ce clic ne redéclenche jamais un enregistrement, il ne fait que clore l'état "attention requise" — le contact concerné est déjà bel et bien enregistré depuis le tout début de la séquence. **Statut.** L'ensemble validé par Jean-Marc au fil des essais réels de la soirée même, aucune modification de code en attente au-delà de ce qui est déjà livré. Deux points laissés ouverts consciemment plutôt qu'oubliés : le contrat à trois issues complet (silencieux/besoin de précision/question à poser) reste à concevoir le jour où un second cas concret en montrera le besoin réel, plutôt que d'être généralisé dès maintenant sur la seule base de ce premier exemple ; et le clic sur "Valider" ne relance aujourd'hui aucune revalidation automatique du champ concerné — à ajouter délibérément si un futur cas le justifie, pas par anticipation. Version : `` avait déjà avancé plus tôt dans cette même session de travail (`V1.14.15` → `V1.15.15`) pour du code livré en amont de cette réflexion ; c'est cette section-ci qui justifie de faire avancer `` de 15 à 17 (16 ayant déjà été utilisé plus tôt le même jour par la section précédente, in fine sans incidence sur la conception d'ASPIC) — nouvelle version : **V1.15.17**. ## 18. Le concept de "Mission" et la faisabilité d'un dialogue simulé avec Claude dans ASPIC (8 septembre 2026) **Origine — une veille concurrentielle qui débouche sur une réflexion de fond.** Jean-Marc, en observant ce que d'autres éditeurs appellent "agents" dans leurs offres, a voulu vérifier sa compréhension du mécanisme avant d'aller plus loin : un "agent" IA, dans la plupart des produits actuels, est une instance d'un modèle de langage à qui l'on fournit un prompt élaboré définissant son identité. Confirmé par Claude, avec un complément en quatre points retenu comme grille de lecture pour la suite de la session : (1) le prompt système (l'identité, le rôle, le ton), (2) le contexte injecté à chaque appel (historique, données de la situation), (3) l'accès à des outils (API externes, lecture/écriture de données — Instagram et consultation de site cités en exemple par Jean-Marc), (4) une éventuelle boucle agentique (plusieurs étapes de raisonnement/action avant de rendre la main). **Correction d'une idée reçue sur le point 2 : un agent IA n'apprend pas de lui-même.** Jean-Marc avait l'impression que chaque exécution d'un agent était "one-shot", sans que l'historique des échanges/activations soit conservé — impression confirmée et nuancée par Claude : le modèle lui-même ne se met jamais à jour au fil des conversations (pas d'entraînement continu), ce qui donne l'illusion d'un apprentissage n'est en réalité que le système autour, qui réinjecte à chaque appel ce qu'il faut retenir. Point explicitement rapproché de ce qu'ASPIC a déjà construit sans le nommer ainsi : le **journalier** et les **consignes** (section 14) sont précisément ce mécanisme de mémoire explicite — de la même façon que Claude lui-même conserve, entre deux fenêtres de conversation, une mémoire de ce projet par relecture d'un fichier, jamais par un modèle qui "se souviendrait" tout seul. **Sur le point 4 (la boucle), une distinction posée par Claude entre deux usages du même mot.** Jean-Marc imaginait un agent à qui l'on fixerait un objectif dans la durée ("mets en place toutes les actions à ta disposition pour que j'obtienne x rendez-vous téléphoniques d'ici la fin du mois"), plutôt qu'une simple boucle d'exécution à l'intérieur d'une tâche ponctuelle (réfléchir → appeler un outil → regarder le résultat → recommencer, jusqu'à rendre la main). Confirmé par Claude : ce sont deux choses différentes, et celle que décrit Jean-Marc — un objectif poursuivi sur la durée, avec des réveils répétés de l'agent — suppose un état persistant (savoir où on en est par rapport à l'objectif) pour décider quoi faire à chaque réveil plutôt que de répéter aveuglément la même action. **Naissance du concept de "Mission".** Pour nommer ce conteneur (objectif + interactions + état, confié à un agent), Jean-Marc a demandé un terme non déjà utilisé dans ASPIC. Plusieurs pistes proposées par Claude (Mission, Mandat, Objectif, Initiative), en écartant explicitement "Affaire" (déjà réservé aux devis/affaires clients, section 14) et "Dossier" (déjà cité comme objet du bureau à l'ancienne, section 11, même si jamais codé). **Terme retenu par Jean-Marc : Mission.** **Les trois niveaux de mémoire, établis par un parallèle explicite avec la façon dont Claude et Jean-Marc travaillent ensemble.** Jean-Marc a lui-même dressé le parallèle : les synthèses que Claude tient à jour dans des fichiers `.md` du projet, transposées à ASPIC en données stockées en base plutôt qu'en fichiers texte. Claude a reformulé et Jean-Marc a validé la distinction en trois niveaux : (1) **le référentiel** (catalogue d'actions, consignes) — stable, ne se met jamais à jour au fil d'une mission ; (2) **la mission en cours** — un brouillon vivant, qui se met à jour tant qu'elle est ouverte (l'équivalent du "Statut actuel" du journal de développement) ; (3) **l'historique des missions closes** — figé une fois la mission terminée, jamais réécrit (l'équivalent des sections déjà déposées des Réflexions stratégiques). Jean-Marc a confirmé cette lecture et précisé un point : les missions sont **étanches entre elles** en termes de mise à jour, mais **un même agent peut gérer plusieurs missions simultanément** — pas une relation un-agent/une-mission. **La clôture d'une mission est une décision du manager, jamais un calcul automatique.** Reprenant l'image d'un dirigeant qui gère son personnel, Jean-Marc a été explicite : l'atteinte de l'objectif n'est ni nécessaire ni suffisante pour clore une mission — *"Aucun résultat, on arrête mais on a appris ! Objectif atteint mais encore du potentiel, on continue !"* — et le manager lui-même apprend, avec l'usage, où placer le curseur. Cohérent avec la discipline déjà en place ailleurs dans ASPIC (numéro de version, validation d'une consigne) : jamais de règle calculée là où un jugement humain est requis. **Une mission close peut inspirer une mission nouvelle — et ça rouvre, sous un autre angle, la question du RAG déjà posée en section 12.** Jean-Marc imagine, après plusieurs mois d'usage, pouvoir dire à un agent *"crée une nouvelle mission, inspire-toi des actions x, y, z"*. Avec peu de missions closes, il peut les citer lui-même — pas besoin de mécanisme de recherche. Claude a fait remarquer que cette même tension, déjà anticipée en section 14 pour les consignes ("le jour où le corpus grossit trop, la question d'une recherche plutôt qu'une inclusion intégrale se reposera"), se posera de la même façon pour les missions : au-delà d'un certain volume, il faudra bien que l'agent retrouve lui-même des missions similaires. Jean-Marc, découvrant cette perspective en la formulant à voix haute, a choisi de la garder en réserve (*"prions pour ne pas en avoir besoin"*) plutôt que de la concevoir maintenant, et a proposé une alternative plus simple pour amorcer le besoin : des critères structurés (agent, nature de l'objectif, thème...) plutôt qu'une recherche sémantique — puis, en cours d'échange, une préférence pour des **tags libres, en nuage**, éventuellement proposés par l'agent lui-même à la clôture d'une mission plutôt qu'une liste fermée à maintenir à la main. Deux usages possibles du nuage de tags identifiés par Claude — une aide visuelle pour Jean-Marc (repérer les thématiques récurrentes) et/ou le mécanisme de recherche de missions similaires pour l'agent lui-même — **non tranché à ce stade, Jean-Marc n'ayant pas encore d'avis arrêté sur lequel des deux (ou les deux) il souhaite.** **Le stockage exhaustif d'une mission ne pose pas de problème de principe, à la différence des trois documents du projet ASPIC-Claude.** Jean-Marc a explicitement validé que, contrairement au journal/aux réflexions stratégiques (où une synthèse condensée est nécessaire), conserver l'intégralité des données d'une mission ne lui semble pas incongru — la mise en pratique (une vraie phase de tests) tranchera si ce principe tient à l'usage. **Précision : post-it et Mission restent deux objets distincts, à des échelles de temps différentes.** Claude avait suggéré de faire du clic sur un post-it (aujourd'hui inerte, voir "reste à faire" du journal) l'ouverture du dialogue d'une mission. Jean-Marc a explicitement écarté ce rapprochement : les post-its (ToDoList) sont conçus pour être de courte durée, une mission est un objet plus substantiel — le dialogue avec l'agent vivra sur un écran séparé. **L'idée de départ, reformulée avec plus de précision : un dialogue simulé avec Claude, intégré à ASPIC, via une clé Anthropic (pas OpenAI cette fois).** Interface envisagée par Jean-Marc : des bulles façon messagerie/SMS, une bulle jaune à droite pour lui, une bulle de la couleur de l'agent (réutilisation naturelle de `AGN_Couleur`, déjà prévu pour les post-its) à gauche pour la réponse. **Le prompt initial d'un type de mission devra rester secret — secret des futurs clients d'ASPIC, pour éviter qu'ils ne le dupliquent ailleurs.** Jean-Marc a confirmé qu'il ne s'agit pas d'une protection absolue contre un acteur déterminé ayant accès au serveur ou aux bases (*"Prions pour que cela n'arrive pas"*, accepté comme un risque résiduel non traité, dans la continuité du constat déjà posé en section 5 sur l'absence de protection réelle du code PHP/JS vanilla), mais d'une protection contre la duplication casuelle par un client. Claude a relié explicitement ce point à la vision déjà posée en section 15 : un catalogue curaté, non ouvert à l'édition libre du client, dont l'évolution pourrait faire l'objet de mises à jour payantes de l'application — Jean-Marc a confirmé être en phase sur ce rapprochement. **Extension évoquée en parenthèse : une demande de consigne initiée par le client via Matilda.** Jean-Marc envisage de permettre à un futur client de demander, en langage naturel, à Matilda de lui créer une nouvelle consigne — demande transmise à Jean-Marc lui-même, qui évaluerait la faisabilité/le réalisme avant de coder et de déployer la mise à jour vers les bases des utilisateurs concernés. Claude a noté que ce mécanisme est la mise en musique concrète de l'idée déjà posée en section 15 (un catalogue restreint, curaté par Jean-Marc, plutôt qu'une création libre côté client) et fournirait, en prime, un flux d'idées de fonctions à généraliser — l'équivalent commercial de la règle déjà appliquée côté code ("généraliser à partir de 3 répétitions constatées", section 6). Jean-Marc a confirmé avoir déjà anticipé la difficulté que soulève la diffusion d'une même mise à jour vers plusieurs bases clientes isolées (modèle retenu en section 5) — y compris la question de la sauvegarde des données que ça soulève à son tour — et a choisi de ne pas creuser ce point maintenant : *"chaque chose en son temps."* **Faisabilité du dialogue avec Claude via l'API Anthropic — confirmée.** Vérification faite par Claude (documentation officielle Anthropic, 8 septembre 2026) : le mécanisme d'intégration est le même schéma que l'appel IA déjà en place pour l'interprétation vocale (`contact_ia_interprete.php`, qui appelle aujourd'hui OpenAI) — un appel serveur PHP vers l'API Messages d'Anthropic, sans changement d'architecture. Points clés : - L'API est, comme celle d'OpenAI, sans mémoire d'un appel à l'autre — chaque requête doit porter l'historique complet de la conversation, ce qui tombe exactement dans le rôle déjà dévolu à la Mission (stockage exhaustif des interactions, voir plus haut). - Le prompt système dispose d'un paramètre dédié, distinct des messages, jamais transmis au navigateur — cohérent avec le secret recherché pour le prompt initial d'une mission. - Les bulles de dialogue restent du HTML/CSS/JS vanilla ordinaire, sans changement de pile technique. - Tarifs vérifiés le 8 septembre 2026 (susceptibles d'évoluer) : Claude Haiku 4.5 (1 $/5 $ par million de tokens entrée/sortie, le plus rapide et le moins cher), Claude Sonnet 5 (2 $/10 $, meilleur compromis), Claude Opus 5 (5 $/25 $), Claude Fable 5.1 (10 $/50 $, raisonnement le plus poussé) — Haiku ou Sonnet identifiés comme candidats de départ à tester en conditions réelles, sans trancher sur le seul papier. - Le "streaming" (réponse affichée mot à mot) est possible mais volontairement écarté d'une première version, pour la même raison qu'ailleurs dans le projet : construire la version la plus simple d'abord (réponse complète affichée d'un coup), ajouter le raffinement plus tard seulement si l'usage réel le justifie. **Statut : orientation actée dans ses grandes lignes, aucun développement engagé.** Jean-Marc prévoit d'ouvrir ce chantier prochainement. Points laissés ouverts pour une prochaine session : - Structure de données de la Mission (quels champs, quel statut de clôture, quelle relation aux agents/consignes existants) — non conçue. - Mécanisme des tags (nuage) : structure (table libre vs liste fermée), usage (visualisation pour Jean-Marc / recherche pour l'agent / les deux), qui les propose — non tranché, à laisser mûrir avec la pratique. - Un éventuel RAG sur l'historique des missions closes, si le corpus grossit — gardé en réserve, non engagé. - Le mécanisme de diffusion d'une nouvelle consigne vers plusieurs bases clientes isolées, et son implication sur la sauvegarde des données — non traité, remis à plus tard. - Conception de l'écran de dialogue (mission dédiée, bulles, choix du modèle Anthropic) — faisabilité confirmée, rien conçu ni codé à ce stade. Session sans aucune ligne de code applicative touchée — seule la partie `` du numéro de version avance, de 17 à 18, premier cas réel d'une session purement dédiée à la réflexion depuis l'instauration du format à trois niveaux (6 septembre 2026, section 15) : **V1.15.18**. ## 19. Refonte de la classification en 9 classeurs — aligner les catégories du bureau sur le cycle de vie réel d'une affaire (9-10 septembre 2026) **Origine.** En marge du chantier de l'écran 2 ("assistants", voir journal de développement section 28), Jean-Marc a repris de son côté la liste des 9 classeurs physiquement posés sur le bureau — mise en place lors d'une session intermédiaire aux alentours du 7 septembre 2026, jamais formellement consignée ni comme décision stratégique ni dans le détail technique du journal (trou de documentation déjà relevé le 8 septembre, voir section 28 du journal). Cette première liste (Consignes, Contacts, Catalogue, Documents, Prospection, Réseaux, En-cours, Factures, Journalier) juxtaposait des catégories de nature hétérogène — des objets métier (Contacts, Factures), une étape de processus (Prospection, En-cours), un mécanisme interne (Consignes) et un attribut d'assistant qui n'a rien à faire dans une classification de documents (Réseaux, qui est en réalité `AGN_Fonction` de l'assistant Nikita) — sans qu'un principe de classement unique les relie. **La nouvelle répartition, pensée comme le cycle de vie d'une affaire plutôt que comme un inventaire d'objets.** Jean-Marc a proposé une liste resserrée à neuf classeurs toujours, mais cette fois organisée dans l'ordre où une affaire se déroule réellement chez lui : **Catalogue** (la liste des prestations réalisables), **Documents**, **Contacts** (cumulant prospects et clients — un contact n'a plus besoin de changer de classeur en devenant client), **Missions** (en cours et réalisées), **Propositions**, **Livraisons**, **Factures**, **Journalier**, **Gestion**. Chaque classeur y a maintenant sa place dans une même logique de progression (de ce qu'on propose à ce qu'on facture), plutôt que de mélanger des objets et des étapes sans hiérarchie commune. **Deux choix de fond, au-delà du simple renommage :** - **Contacts cumule prospects et clients.** Un même classeur pour tout le cycle de la relation — cohérent avec la donnée déjà en place côté base (aucune distinction structurelle entre prospect et client dans `ASP_Contacts`, seul le contenu réel des échanges le dit) : la classification suit ici la réalité déjà actée du modèle de données, plutôt que de recréer une frontière artificielle. - **Consignes disparaît de la vue "classeurs".** Cohérent avec la nature même de ce mécanisme (sections 14, 15, 17) : une consigne est un réglage du fonctionnement des assistants, pas un document ou une affaire à classer — elle n'avait sa place dans les classeurs du bureau que par un raccourci de mise en œuvre initiale, pas par nature. Elle continuera d'exister comme mécanisme (table `ASP_Consignes`, futur écran de gestion évoqué en section 15), simplement plus comme un classeur visible du bureau à l'ancienne. **Une contrainte assumée, pas subie : rester dans la limite de 9 classeurs.** Jean-Marc s'est explicitement imposé de retrouver une classification cohérente sans dépasser le nombre de classeurs déjà physiquement dessinés sur l'avant-plan du bureau (section 28 du journal, image fixe fournie le 8 septembre) — la contrainte visuelle existante a été un guide pour la réflexion business, pas un obstacle à contourner en redessinant l'image. **Répercussion technique, anticipée par construction plutôt que découverte après coup :** la conservation des 9 positions physiques exactes (mêmes coordonnées x1/x2/étiquette sur l'image de référence, seuls les libellés et identifiants changent) a permis un renommage sans aucune retouche de l'avant-plan. Un seul point de vigilance identifié et corrigé avant livraison, propre à ce changement précis : la pastille de comptage des contacts (`PASTILLE_CONTACTS_CENTRE_X`) était positionnée par une coordonnée **indépendante** du tableau des classeurs, calée sur l'ancienne 2ᵉ position — un renommage naïf des seuls libellés l'aurait laissée sous "Documents" au lieu de suivre "Contacts" à sa nouvelle 3ᵉ position. Voir journal de développement, section 28, pour le détail technique de cette correction. **Statut.** Décision actée et codée le soir même (voir journal, section 28, pour le détail des 9 classeurs et de leur position). Rien de plus engagé sur le contenu réel de chacun de ces classeurs (Missions, Propositions, Livraisons et Gestion n'ont, à ce stade, aucun écran ni donnée derrière eux — seul Contacts reste fonctionnel) : cette section fixe la classification cible, pas son implémentation fonctionnelle classeur par classeur, qui reste à construire un par un. Cette clarification du classement documentaire est jugée par Jean-Marc suffisamment structurante pour faire avancer la partie `` du numéro de version — `` avait déjà avancé en tout début de cette même session (V1.17.18 → V1.18.18) pour le code produit ce soir sur l'écran des assistants ; cette section fait avancer `` de 18 à 19 : nouvelle version **V1.18.19**. ## 20. Donner une identité aux collaborateurs — un chemin médian entre l'agent robotique et l'avatar-compagnon malsain (10 septembre 2026) **Origine — un mot qui ne convenait plus.** Jean-Marc a constaté que son propre discours avait glissé, sans décision explicite, d'« agents » à « assistants », et a voulu franchir une dernière étape terminologique : « collaborateurs ». **Choix assumé dès le départ : ce changement reste strictement un habillage côté utilisateur** — la table `ASP_Agents`, les colonnes `AGN_*` et `agents.php` ne sont pas touchés (« c'est notre cuisine interne », dans les mots de Jean-Marc) : seul le panneau de l'écran des collaborateurs change de libellé (« Bureau des assistants » → « L'équipe des collaborateurs »). **Le vrai sujet derrière le mot : quelle identité donner à ces cinq collaborateurs.** Jean-Marc a partagé une observation tirée de sa veille sur le secteur : deux écueils opposés dans la façon dont l'IA est présentée aujourd'hui — d'un côté l'« agent IA » présenté comme un outil technique impersonnel (peu engageant, difficile à déléguer sincèrement comme à un collègue), de l'autre des cas rapportés dans les médias d'avatars-compagnons IA créant une dépendance affective malsaine chez leurs utilisateurs. **Décision de principe : viser un chemin médian, délibérément à distance des deux extrêmes** — donner aux collaborateurs une identité humaine crédible (un visage réel via `AGN_Photo`, déjà en place ; un rôle professionnel concret plutôt qu'une étiquette générique, ex. Matilda passe d'« Administration » à « Assistante de direction ») sans jamais glisser vers un registre relationnel de type compagnon. **Le garde-fou de confidentialité, posé avant tout développement.** Jean-Marc a été explicite : le parcours de vie et la personnalité de chaque collaborateur (mémoire, expérience professionnelle, façon de voir les choses) ne doivent **jamais** être consultables tels quels par un utilisateur — seule une présentation synthétisée, dans les mots du collaborateur lui-même et selon son caractère propre, pourra un jour en être tirée, en dialogue. Ce principe structure directement l'architecture retenue (voir plus bas) : un champ dédié (`AGN_Identite`), lu par un endpoint séparé de l'endpoint public `agents.php`, jamais renvoyé à un écran utilisateur ordinaire. **Un trait de caractère assumé : des avis qui peuvent diverger.** Interrogé sur la possibilité que deux collaborateurs (ou un collaborateur et Jean-Marc lui-même) ne soient pas d'accord, Jean-Marc a répondu sans détour : « magnifique, la vraie vie ! » — un désaccord renforce, plutôt qu'il ne fragilise, la nécessité de trancher, rôle qui revient explicitement au « boss ». Point à retenir pour tout prompt système futur bâti sur ce mécanisme : la personnalité doit pouvoir influencer un ton, un jugement, une préférence — jamais neutraliser l'IA en une voix unique et consensuelle. **Opérationnalisé le soir même, directement sur l'écran des collaborateurs plutôt qu'en outil à part.** Jean-Marc a explicitement écarté une première piste (un outil interne séparé), de peur qu'un outil isolé « fasse passer à côté de plein de choses » : la mécanique retenue est intégrée à `ecran_fond.html` lui-même, deux boutons sous le panneau des collaborateurs : - **« Construire une identité »** — écran plein cadre, terminal de saisie repris tel quel d'un collaborateur à l'autre. - **« Tester l'identité »** — même écran, mais avec une vraie fenêtre de dialogue (façon session de chat), branchée sur l'API Anthropic (`ANTHROPIC_API_KEY`, acquise par Jean-Marc ce jour — apprentissage en cours de route : une clé « organisation » plutôt que liée à un espace de travail précis échoue sur l'API avec une erreur explicite, résolu en recréant la clé correctement scopée). **Un enseignement relevé en cours de route, qui dépasse ce seul écran : l'identité est un document vivant, pas une biographie figée.** Jean-Marc a corrigé une hypothèse implicite de Claude (« ce champ n'atteindra jamais sa limite de toute façon ») en rappelant l'intention de fond : l'expérience vécue par un collaborateur au fil de l'usage réel de l'application (missions menées, réunions, compétences acquises — voir la Mission, section 18) a vocation à venir **enrichir** son identité avec le temps, pas seulement la déclarer une fois pour toutes à l'embauche. Conséquence technique immédiate : la colonne `AGN_Identite`, initialement `TEXT` (65 535 octets), élargie le soir même en `MEDIUMTEXT` (16 777 215 octets) pour ne jamais devenir un plafond réel sur la durée de vie d'un collaborateur — avec un indicateur d'occupation ajouté à l'écran de saisie pour que ce plafond, même repoussé très loin, reste visible plutôt que découvert par surprise le jour où il serait atteint. **Statut.** Mécanisme construit, testé et validé par Jean-Marc en conditions réelles le soir même (« les deux outils fonctionnent parfaitement et passer de l'un à l'autre est vraiment idéal »). Premiers textes d'identité en cours de rédaction par Jean-Marc lui-même (Matilda déjà saisie), à la première personne plutôt qu'à la troisième — choix motivé par le fait qu'un texte écrit comme les propres notes intimes du collaborateur aide davantage le modèle à en adopter la voix qu'une biographie racontée de l'extérieur. Points laissés ouverts pour une prochaine session : le lien concret entre une Mission close (section 18) et l'enrichissement réel de `AGN_Identite` — non conçu, seule l'intention est actée ici — et le contenu même des cinq identités, encore à écrire. ## 21. Stockage de documents utilisateur (PDF) — anticiper l'architecture et les risques avant le premier octet écrit (10 septembre 2026) **Origine.** Question posée par Jean-Marc en marge des échanges du jour, sans besoin immédiat identifié (« ce n'est pas que je pense saturer le champ aujourd'hui ») mais avec la conviction qu'il faudra, à un moment donné, permettre à un utilisateur d'ASPIC de stocker des PDF (documents commerciaux, contrats...) — et une inquiétude explicite sur les risques que ça peut ouvrir. **Les risques identifiés, par ordre d'importance réelle plutôt que d'intuition première.** Le danger le plus concret n'est pas « un PDF piégé qui infecte le serveur » (peu probable en pratique), mais l'exécution de ce qui est déposé : un fichier renommé en `.pdf` mais en réalité exécutable, s'il atterrit dans un dossier que le serveur web sait interpréter, ouvre une vraie brèche — d'où la nécessité de ne jamais faire confiance à l'extension ni au `Content-Type` envoyé par le navigateur (trivialement falsifiable), de vérifier la signature réelle du fichier (`%PDF-` en tête), et surtout d'empêcher toute exécution de script dans le dossier de stockage lui-même. Viennent ensuite : le risque de traversée de chemin si un nom de fichier fourni par l'utilisateur sert tel quel à construire un chemin serveur ; le fait qu'un PDF n'est pas un format inerte (JavaScript embarqué possible, à ne jamais ouvrir « en confiance » côté serveur) ; le contrôle d'accès (un document lié à un contact ne doit jamais être joignable par une URL directe devinable) ; et une limite de taille raisonnable pour éviter la saturation du disque du VPS. **La question posée explicitement par Jean-Marc : où stocker ces fichiers, dans un répertoire propre à chaque utilisateur, sans qu'il en connaisse le chemin exact ni même le nom réel sur le disque.** **Réponse retenue — la protection réelle n'est pas l'obscurité du chemin, c'est son inaccessibilité totale au navigateur.** Cacher un chemin (le rendre difficile à deviner) reste une protection secondaire et insuffisante prise seule — si un fichier reste malgré tout servi directement par le serveur web, un chemin fini toujours, tôt ou tard, par pouvoir être deviné, journalisé quelque part, ou exposé par une erreur de configuration. La vraie architecture retenue va plus loin que ce que Jean-Marc demandait littéralement, dans l'esprit de sa demande : - **Stockage hors de la racine servie par le serveur web** — le dossier de documents ne se trouve tout simplement pas dans l'arborescence qu'Nginx/Apache sait servir. Aucune URL directe ne peut donc jamais atteindre un fichier, quel que soit son nom ou son chemin. - **Tout accès passe par un endpoint PHP dédié**, sur le même principe que le reste d'ASPIC (`$_SESSION['USR_Code']` vérifiée avant toute lecture) — c'est lui, et lui seul, qui résout en interne quel fichier physique correspond à quel document, jamais le navigateur. - **En complément (défense en profondeur, pas le mécanisme principal) :** un sous-dossier par compte client, nommé par un identifiant interne opaque plutôt que par un code déjà visible ailleurs dans l'application ; et un nom de fichier généré aléatoirement sur le disque (le nom réel du document — celui que Jean-Marc ou son client voit à l'écran — ne vivant qu'en base, dans une table de métadonnées séparée du fichier lui-même). Cette organisation par compte a aussi un bénéfice direct pour le modèle SaaS envisagé (section 5) : un client = un dossier, facilement exportable ou supprimable en bloc. Dans cette architecture, peu importe finalement que Jean-Marc « connaisse » ou non le chemin ou le nom réel d'un fichier — la question ne se pose plus, puisqu'aucune voie d'accès ne passe jamais par là. **Statut.** Aucun développement engagé — réflexion volontairement anticipée, avant tout besoin réel, pour que le premier fichier réellement stocké le soit déjà dans la bonne architecture plutôt que dans une version à corriger après coup. Reste à concevoir le jour venu : la table de métadonnées (nom d'origine, type, taille, contact/mission lié, propriétaire, date), l'endpoint de dépôt et l'endpoint de téléchargement, sur les mêmes conventions défensives déjà en place ailleurs dans ASPIC (vérification de session, requêtes préparées, erreurs explicites plutôt que silencieuses). `` avait déjà avancé en tout début de cette même session (V1.18.19 → V1.19.20) pour le code livré ce jour sur l'écran des collaborateurs ; ces deux nouvelles sections (20 et 21) font avancer `` une seconde fois au cours de la même session, de 20 à 21 — nouvelle version **V1.19.21**. ## 22. Le concept de "compétence" — donner à un collaborateur une capacité réelle d'agir, et jusqu'où (10-11 septembre 2026) **Origine — un collaborateur qui réclame ce qu'il n'a pas.** En testant l'identité de Sophia (section 20), Jean-Marc l'a vue lui demander spontanément des informations et des fichiers pour "créer des sites web" — alors qu'elle n'a jamais eu la moindre capacité réelle d'agir, seulement une conversation. Claude a noté que ce n'est pas dangereux en soi (rien ne peut se passer sans outil réel), mais révélateur : rien dans son identité ni son prompt système ne la borne sur ce qu'elle peut légitimement proposer — un collaborateur non briefé "invente" son périmètre. Jean-Marc a validé cette lecture explicitement : *"c'est à moi de la canaliser"*, en la limitant demain aux seules compétences dont elle aura été dotée. **Reformulation du besoin par Jean-Marc, plus large que le cas Sophia.** Plutôt que de traiter "donner à Sophia la capacité de faire des sites" comme un besoin isolé, Jean-Marc a explicitement relié le sujet à un chantier de fond resté en suspens depuis le 8 septembre : le concept de **Mission** (section 18), posé dans ses grandes lignes mais jamais conçu en détail. Doter un collaborateur de **compétences** est la pièce manquante qui permet à une Mission d'exister concrètement : quelles compétences un collaborateur possède, quelles compétences une Mission requiert pour être réalisable. Point de méthode assumé par Jean-Marc, qui découvre l'usage réel de Claude/des LLM en marge de ce chantier : *"j'ai besoin d'être assisté"* — le sujet a été traité comme un apprentissage autant que comme une conception. **Ce qu'une "compétence" signifie réellement, techniquement.** Point pédagogique important établi en cours d'échange : côté Anthropic, il n'existe aucune notion de "compétence" — seulement un mécanisme d'outils (tools) déclarés à chaque appel, que le modèle peut choisir d'invoquer, jamais exécuter lui-même. "Doter" un collaborateur d'une compétence se traduit donc concrètement par deux choses combinées : quels outils apparaissent réellement dans la liste envoyée pour lui (une compétence non accordée = un outil absent, pas juste déconseillé), et ce que son prompt système lui dit avoir le droit de faire — pour éviter exactement l'épisode qui a lancé cette réflexion. **Le périmètre business tranché avant toute conception technique.** Jean-Marc a été explicite et sans détour sur ce que la compétence "sites web" ne doit jamais devenir : Sophia ne produit des sites que pour l'entreprise qui exploite ASPIC elle-même, jamais pour un client tiers de cette entreprise — *"il faut rester dans le périmètre d'un CRM !"*. Elle ne travaille qu'à partir des documents de l'entreprise, doit pouvoir mettre à jour un site déjà créé (retours clients, nouveaux produits du catalogue), et une fois ses créations validées, doit pouvoir les faire publier. Une nuance importante s'est imposée en creusant ce dernier point : la validation et la publication restent des actes humains — cohérent avec le principe déjà posé pour la clôture d'une Mission (section 18, *"la clôture d'une mission est une décision du manager, jamais un calcul automatique"*) : la même discipline s'applique à la mise en ligne d'un livrable produit par un collaborateur. **Le stockage — un cas différent du coffre-fort documentaire de la section 21, pas une extension de celui-ci.** Jean-Marc a d'abord été réticent à l'idée d'un stockage "sur le disque dur local de l'utilisateur", inquiet de devoir retrouver ses données en changeant d'ordinateur d'un jour à l'autre — un malentendu levé en clarifiant qu'aucun stockage local n'était en jeu, tout vivant côté serveur, déjà accessible identiquement depuis n'importe quelle machine. La vraie question restait la bonne clé d'isolement par entreprise. Contrairement au coffre PDF (section 21, où l'inaccessibilité totale au navigateur est le principe même), un site web doit au contraire être servable — la section 21 ne pouvait donc pas être simplement recopiée, seulement inspirée dans son esprit (hors racine tant que brouillon, accès contrôlé). Confirmation apportée par Jean-Marc que plusieurs sites pourront coexister pour une même entreprise (deux domaines réels déjà en tête : `mevelia-solutions.bzh` pour la future agence, `aspic.bzh` pour le CRM lui-même une fois commercialisé) — le modèle retenu autorise nativement cette pluralité. **Une précision de fond sur `AGN_Identite`/`AGN_Experience`, qui affine la section 20.** En repensant au mécanisme de clôture d'une Mission, Jean-Marc a corrigé une ambiguïté laissée par la section 20 : ce n'est pas l'identité d'un collaborateur qui s'enrichit avec l'usage, c'est son **expérience** — `AGN_Identite` reste le profil fixe à l'embauche, volontairement écrasable si Jean-Marc veut corriger un trait de caractère ; `AGN_Experience` est ce qui se met à jour à la clôture d'une mission, jamais réécrit, seulement accumulé. Séparer les deux champs dès le 10 septembre (section 20) s'avère avoir anticipé, sans le nommer alors, exactement cette distinction. **Une question laissée volontairement ouverte par Jean-Marc, reconnue comme le sujet le plus intéressant du chantier : comment un collaborateur évolue-t-il vraiment avec l'expérience ?** Claude a rappelé un fait déstabilisant mais déjà entrevu en section 18 : le modèle lui-même n'apprend jamais rien, une session à l'autre — ce qui ressemble à une évolution du collaborateur n'est que le texte accumulé dans `AGN_Experience`, réinjecté intégralement à chaque appel. Jean-Marc a validé cette mécanique comme **souhaitable**, pas comme une limite à contourner : *"un fonctionnement différent voudrait dire que le LLM apprend de mon utilisation, ce que je n'ai ni la prétention ni l'intention de faire"* — la mémoire reste ainsi entièrement éditoriale, sous le contrôle de Jean-Marc (correction, purge, gel possible à tout moment), jamais une boîte noire qui dériverait toute seule. Question laissée en réserve pour une prochaine session : à partir de quel volume ce texte accumulé devra-t-il être résumé plutôt qu'injecté intégralement (même tension déjà identifiée pour les consignes et les missions, sections 12/18) — et si une remise à zéro complète de l'expérience d'un collaborateur sera un jour nécessaire (l'échappatoire existe déjà, via "Modifier l'expérience", simplement jamais pensée jusqu'ici comme une réinitialisation). **Statut.** Conception validée et codée dans la foulée de cette même session (voir journal de développement, section 31, pour le détail technique : tables, endpoints, boucle agentique, premier essai réel). Points laissés ouverts, actés ici comme sujets de fond plutôt que comme détails techniques : le mécanisme réel de clôture d'une Mission (comment un bilan de mission vient concrètement enrichir `AGN_Experience`) ; le seuil à partir duquel l'expérience accumulée d'un collaborateur devra être résumée plutôt qu'injectée en entier ; la question, gardée en réserve, d'une remise à zéro de mémoire. `` avance également au cours de cette même session (chantier décrit en détail au journal de développement, section 31) — nouvelle version **V1.21.22**. ## 23. Services externes ou développement interne pour les compétences des collaborateurs — premier cas réel, le site web (11 septembre 2026) **Origine.** Après avoir vu la compétence "site web" fonctionner (section 22), Jean-Marc s'est demandé s'il n'était pas en train de "réinventer l'eau chaude" — et s'il ne vaudrait pas mieux faire appel à un agent/service déjà existant plutôt que tout construire lui-même. **Distinction posée par Claude entre le mécanisme et l'intégration.** Le "tool use" lui-même (déclarer des outils, boucler, exécuter côté serveur) est effectivement un patron générique, documenté par Anthropic, sans originalité — l'équivalent d'utiliser une prise électrique standard. Ce qui n'est pas de l'eau chaude, c'est l'intégration : aucun service externe grand public ne connaît Sophia, sa mémoire, ni les règles métier posées par Jean-Marc (jamais pour un client tiers, publication toujours validée par lui) — un outil externe rendrait le même service technique, mais casserait la valeur ajoutée réelle (une collaboratrice qui reste elle-même). **Recherche réelle effectuée le même soir** sur les services existants de génération de site vitrine, avec un critère de filtrage strict : seuls comptent les services offrant une vraie **API programmable** (pas une interface de chat humaine) permettant de déclencher une génération et d'en récupérer le résultat par un appel HTTP. Résultat : sur une dizaine d'acteurs examinés (v0/Vercel, Bolt.new, Lovable, Framer AI, Durable.co, 10Web, Wix, GoDaddy Airo, Webflow...), **seuls deux** correspondent vraiment au besoin — et aucun des deux n'apporte de gain net pour un site vitrine strictement statique : - **10Web** : une vraie API prompt→site en un appel, mais impose une sortie **WordPress** (PHP + base de données), pas du HTML/CSS statique comme ce qu'ASPIC produit déjà. Tarif de production non public (sur devis). - **v0 (Vercel)** : API tarifée publiquement (20-30$/mois + facturation token), mais renvoie du **code** (React/Next.js) nécessitant un déploiement séparé, pas un résultat clé en main. **Réserve explicite sur la fiabilité des tarifs trouvés** : la quasi-totalité des chiffres 2026 proviennent de blogs tiers/affiliés, pas des pages officielles des éditeurs — non vérifiables à 100% sur une source primaire. **Conclusion retenue par Jean-Marc, qui devient une règle de décision générale plutôt qu'un simple constat ponctuel :** pour la compétence "site web" précisément, garder ce qui a été construit en interne — aucun service externe ne fait mieux sans changement d'architecture. Mais Jean-Marc a profité de l'occasion pour repréciser les **trois objectifs fondateurs** qui motivent tout le projet ASPIC depuis le début : (1) se doter enfin d'un outil efficace, longtemps rêvé sans jamais l'avoir eu dans ses expériences professionnelles passées ; (2) casser la sensation de solitude du patron de petite structure, y compris vis-à-vis de l'extérieur, via des collaborateurs humanisés à mémoire persistante ; (3) optionnellement, vendre ASPIC en SaaS si l'outil fonctionne bien et que la demande existe. **Décision de méthode pour les prochains chantiers (prospection, réseaux sociaux...) :** au cas par cas, préférer un service externe existant pour les grosses fonctionnalités à venir — le temps disponible avant 2027 ne permet pas de tout construire à la main comme pour le site web (une soirée entière pour une seule compétence). Une fois l'expérience acquise avec ces services externes (ce qui marche, ce qui déçoit), Jean-Marc envisage une "Phase II" d'internalisation ciblée, avec l'aide de Claude, en capitalisant sur cette expérience plutôt qu'en devinant à l'avance ce qui vaudra la peine d'être ramené en interne. **Point pédagogique retenu, pour distinguer un cas qui nécessite un outil d'un cas qui n'en nécessite pas** (exemple discuté : faire rédiger un article web à Sophia à partir d'un texte source) : la question à se poser est "est-ce que le résultat attendu EST le texte de sa réponse, ou est-ce que quelque chose doit changer en dehors de la conversation (fichier écrit, donnée enregistrée, action déclenchée) ?" Dans le premier cas (rédaction pure), un bon prompt suffit — le "savoir-faire" rédactionnel n'est pas un outil à fabriquer, il est déjà dans le modèle, le prompt se contentant de l'orienter (ton, structure, longueur des phrases). Dans le second cas (écrire un fichier, publier, aller chercher une donnée non fournie), un outil réel est indispensable, quelle que soit la qualité du prompt — c'est le prompt qui donne le contexte, jamais la capacité d'agir. **Statut.** Décision actée : pour le site web, développement interne conservé ; pour les prochains grands chantiers, priorité aux services externes, réévaluation possible après usage réel. Rien d'autre engagé à ce stade — cette section fixe le cadre de décision, pas un choix définitif compétence par compétence. `` n'avance pas dans cette section (aucune ligne de code applicative touchée par cette réflexion elle-même — le code livré ce soir, décrit au journal de développement section 32, avait déjà fait avancer ce compteur avant cette discussion) ; `` avance de 22 à 23 — nouvelle version **V1.22.23**. ## 24. Quatre facettes de la mémoire d'un collaborateur, et sortir le patron du code (11 septembre 2026) **Origine.** En testant le panneau "Compétences" tout juste ajouté au BackOffice (voir journal de développement, section 33), Jean-Marc a attribué par jeu à Sophia la compétence "savoir faire un bon café" — et l'a vue, dans "Tester", la citer et la commenter comme n'importe quelle compétence réelle. Révélateur d'un flou plus large que ce seul bug : qu'est-ce qui distingue vraiment, dans la mémoire d'un collaborateur, ce qui relève du caractère, de la capacité, de l'histoire vécue et de la relation ? **Le modèle à quatre facettes, posé par Jean-Marc en cours d'échange.** Trois champs existaient déjà, chacun avec un rôle propre mais pas toujours net dans son esprit : 1. **Identité** (`AGN_Identite`) — ce que la personne *est* : caractère, goûts, ce qui ne dépend pas de son emploi chez Jean-Marc. 2. **Compétences** (`ASP_Competences`) — ce qu'**ASPIC lui apporte** comme capacité réelle, mécanique par nature (aucun effet sans câblage dans `mission_agent.php`, voir section 22) : *"même si personne n'arrive dans une boîte sans rien savoir faire, on n'est pas là pour faire le CV des collaborateurs !"* 3. **Expérience** (`AGN_Experience`) — ce qui s'accumule par append au fil des dialogues réels, mémoire éditoriale sous contrôle de Jean-Marc (section 22). Restait un point sans case évidente : la dimension relationnelle envers l'équipe, jusque-là diluée dans l'identité de chacun — *"je ne sais pas où caser l'aspect relationnel avec l'équipe qui donne selon moi du sens à l'ensemble. Je l'ai mis jusqu'à présent dans l'identité, ce n'est pas complètement cohérent..."* Clarification retenue avec Claude : une posture relationnelle *initiale* (directe, réservée, chaleureuse...) est un trait de caractère comme un autre, mais la relation *vécue* se construit avec le temps — elle ressemble par nature à ce que l'Expérience capte déjà, plutôt qu'à un trait figé. Jean-Marc a néanmoins choisi d'ouvrir une quatrième facette dédiée (**`AGN_Relationnel`**, statique pour l'instant) plutôt que de forcer cette idée dans l'un des trois champs existants — la distinction reste plus nette pour lui à l'écriture, quitte à ce que la frontière avec l'expérience s'affine à l'usage. **Le café n'était pas un bug, mais un défaut de garde.** Diagnostic technique du symptôme de départ : `AGN_Identite`/`AGN_Experience` sont protégées dans le prompt par une consigne explicite ("aide-mémoire, jamais à réciter"), mais le bloc compétences ne l'était pas — un oubli de conception, pas une fatalité du modèle. Corrigé (détail au journal, section 33). Point de méthode qui en découle, généralisable : tout champ injecté dans un prompt système comme mémoire d'un collaborateur doit porter la même garde, faute de quoi il devient une donnée à réciter au lieu d'un aide-mémoire — l'oubli sur les compétences n'est probablement pas le dernier de ce genre. **Sortir les prompts eux-mêmes du code — même geste que les consignes, appliqué un cran plus haut.** Demande explicite de Jean-Marc, dans la foulée : *"j'aimerai bien que ces prompts ne soient plus dans le code mais me soient accessibles"* — étendue par lui à l'ensemble des quatre prompts IA du projet plutôt qu'au seul dialogue collaborateur. Même philosophie que le chantier des consignes (sections 15/17) et le catalogue de compétences (section 22) : ce qui relève du jugement de Jean-Marc plutôt que de la logique du programme ne doit pas vivre en dur dans un fichier PHP. Concrètement, une table `ASP_Prompts` et un mécanisme d'auto-amorçage (le texte d'origine, gardé en code comme filet, crée sa propre ligne en base au premier besoin réel) — détail complet au journal, section 33. **Le "aha" du prénom en dur — un premier pas concret vers un ASPIC réutilisable.** En écrivant le relationnel de Sophia (qui mentionne "le patron"), Jean-Marc a réalisé, de lui-même, un point resté invisible jusqu'ici : *"il n'est pas bon que mon prénom apparaisse dans le code si demain l'application est fournie à Joseph ou à Sylvie !"* Lien direct et explicite avec le troisième objectif fondateur d'ASPIC, la vente en SaaS (section 23) — jusqu'ici une intention lointaine, jamais confrontée à un détail concret d'implémentation. Toutes les occurrences de "Jean-Marc" réellement transmises à un modèle (dans les deux prompts système concernés, et dans le journal texte d'une mission) ont été remplacées par le prénom de la session en cours (`USR_Prenom`, déjà connu du système à l'identification) — aucune nouvelle donnée à saisir, juste arrêter de figer par erreur une donnée qui n'a jamais eu vocation à être fixe. Premier cas concret, mineur en soi, mais qui rend tangible une question qui restera à se poser systématiquement à mesure qu'ASPIC grandit : qu'est-ce qui, dans le code, suppose implicitement "Jean-Marc" comme seul patron possible ? **Statut.** Modèle à quatre facettes adopté et codé le soir même (voir journal de développement, section 33) ; prompts sortis du code pour les quatre cas réels du projet ; dé-figement du prénom du patron traité comme un premier cas d'école, pas comme un chantier de "multi-tenant" en soi — aucune autre donnée de ce type recherchée systématiquement à ce stade. `` avance également au cours de cette même session (détail au journal de développement, section 33) — nouvelle version **V1.23.24**. Point de méthode noté au passage (voir Index) : `` est un compteur libre, incrémenté à chaque évolution jugée majeure — **il ne correspond pas** au numéro que prend la section ci-dessus dans ce document (24), malgré une coïncidence numérique fréquente ces derniers jours. ## 25. Prospection B2B — mutualisation de la ressource entreprises, architecture Phase1/2/3, et découverte de la prospection par géographie personnelle (11-12 septembre 2026) **Origine.** Une coupure de session dans la nuit du 11 au 12 septembre (timeout du proxy devant le terminal web, sans rapport avec ASPIC — voir journal d'infrastructure) a fait perdre le fil de ce qui avait été lancé la veille au soir : l'extraction Sirene/RNE quasi-exhaustive du Morbihan, décidée section 23 comme canal gratuit de démarrage pour la prospection B2B. Reconstitué avec Jean-Marc au réveil, puis vérifié par comparaison avec l'API Sirene officielle (département 56, tranche par tranche d'effectif) : les 167 468 lignes de `ASP_EntreprisePhase1` sont bien le résultat complet voulu, pas un traitement resté à mi-chemin — écart de 9 lignes sur les tranches connues, imputable à la fraîcheur des données entre l'extraction et la vérification, pas à un trou réel. **La réflexion nocturne de Jean-Marc, double.** D'une part, pour lui-même : ASPIC peut désormais lui fournir une base de prospection déjà constituée gratuitement, pour se concentrer sur la sélection et la qualification plutôt que sur la collecte. D'autre part, une prise de conscience plus large, déclenchée par un ami rennais dans une situation de projet proche (formation en cours, création de société prévue en janvier 2027) : cet ami envisage uniquement des moyens de prospection passifs (site, bouche-à-oreille, publicité), faute de savoir aborder une prospection active — situation à laquelle Jean-Marc n'avait pas encore songé à le confronter. Conclusion : la ressource en cours de constitution a suffisamment de valeur pour justifier de sortir son organisation du cadre strictement personnel envisagé jusque-là. **Décision de mutualisation.** La table sort de l'environnement MySQL personnel de Jean-Marc pour rejoindre l'instance `mysql2` — celle qui héberge déjà MIRADOR, la base d'authentification centralisée commune à tous les utilisateurs d'ASPIC (voir section sur MIRADOR, journal de développement). Nouvelle base dédiée : `ENTREPRISES`. Architecture retenue à cette occasion, avec une distinction de principe qui devra rester vraie même quand ASPIC aura plusieurs utilisateurs réels : les données Sirene/RNE brutes (identité, effectif, finances) sont publiques et doivent être **partagées** (une seule synchronisation profite à tous, jamais de copie qui dérive) ; les données de qualification/prospection (statut, canal, notes, rendez-vous) doivent rester **propres à chaque utilisateur/compte**, pour qu'un jour deux prospecteurs ne risquent pas de démarcher la même entreprise sans le savoir l'un de l'autre. **Une table par département plutôt qu'une table nationale unique**, vu le volume (167 468 lignes pour le seul 56) : `EntreprisesXXPhase1`/`Phase2`/`Phase3` (XX = code département), colonnes uniformément préfixées `ENT_` (la phase étant déjà portée par le nom de table, inutile de la répéter dans le préfixe de colonne comme le faisait l'ancien `EP1_`/`EP2_`). **`ENT_Communes`, seule table volontairement partagée entre tous les départements** (une ligne par commune, code INSEE en clé) — pour deux raisons distinctes de celle qui vaut pour les finances (voir plus bas) : jamais de doublon possible (une commune n'appartient qu'à un seul département), et surtout, la recherche de proximité doit pouvoir **traverser une frontière départementale** sans que l'utilisateur ait à s'en soucier — une commune du 35 peut être à dix minutes d'une commune du 22. **Découverte capitale de la soirée : le calcul d'isochrone par l'IGN (Géoplateforme, `data.geopf.fr/navigation/isochrone`)**, service public gratuit et sans clé, fondé sur le réseau routier réel (BD TOPO®) — pas une distance à vol d'oiseau. Un seul appel avec un point de départ quelconque (pas forcément une adresse personnelle) et une durée en minutes renvoie le polygone exact de la zone accessible en voiture ; test réel réussi (30 minutes depuis Lorient → 19 communes environnantes, cohérentes avec la géographie du secteur). Ceci ouvre à Jean-Marc une façon de travailler qu'il juge nouvelle : construire sa tournée de prospection autour de ses propres déplacements (exemple donné : 15 jours à Saint-Malo avec sa compagne) plutôt que l'inverse — la géographie personnelle devient le point de départ de l'organisation commerciale, pas une contrainte à laquelle elle doit se plier après coup. **Phase3 — l'historique financier, seule question réellement débattue ce soir.** Constat vérifié sur les données réelles du 56 : le champ `finances` de l'API ne renvoie jamais qu'**une seule année à la fois** par entreprise (15 010 entreprises concernées sur 167 468, jamais plus d'une année chacune) — pas une fenêtre glissante de plusieurs années comme le suggérait la documentation générale. Toute resynchronisation qui écraserait ce champ perdrait donc purement et simplement l'année précédente, pas seulement une lointaine année n-4. Décision : `EntreprisesXXPhase3`, table étroite (SIREN, année, CA, résultat net, date de maj), clé composite `(SIREN, année)`, alimentée en `INSERT ... ON DUPLICATE KEY UPDATE` — une nouvelle année crée une nouvelle ligne, elle ne touche jamais celles des années déjà connues. Question annexe tranchée en sens inverse de `ENT_Communes` : Phase3 reste **par département**, pas globalisée — les finances d'une entreprise n'ont pas de besoin de continuité géographique inter-départementale comme les communes, et le prix d'une table nationale unique (clauses `WHERE` partout pour retrouver "les finances des entreprises du 29") ne se justifie pas face au bénéfice réel (éviter la rare duplication d'un SIREN présent dans plusieurs départements). **Script d'extraction générique, hors dépôt applicatif** (`/docker/aspic/scripts/sirene_extract.py` — délibérément à côté de `src/`, pas dans le code d'ASPIC lui-même, cohérent avec la décision de la section précédente : ce chantier reste "à la mimine" avant toute intégration éventuelle dans l'app). Il crée les trois tables par département à la volée, découpe automatiquement les requêtes par commune puis par section NAF quand une commune dépasse à elle seule le plafond de 10 000 résultats de l'API (deux communes seulement en ont eu besoin sur les 249 du Morbihan : Lorient et Vannes), et neutralise proprement les cas limites découverts en le testant sur trois départements réels (Morbihan en migration, Lozère en test, Finistère en cours) : entités en diffusion partielle RGPD (`[NON-DIFFUSIBLE]`), sièges sociaux à l'étranger (codes postaux non-français), qualités de dirigeant cumulées dépassant la largeur de colonne prévue. **Confirmation et chiffrage de décisions déjà actées.** Le rejet du scraping LinkedIn (section du 11 septembre) reste confirmé sans hésitation. Les tarifs réels des prestataires de fichiers de contacts complets (dirigeant + email + téléphone) ont été recherchés : 0,15 à 0,50 €/contact à l'achat, 2 à 5 €/contact chez Kompass avec abonnement minimum ~3000 €/an — jugés trop coûteux pour une société qui démarre, ce qui renforce la méthode déjà actée (qualifier gratuitement via Sirene avant d'acheter ou d'enrichir le contact). **Pistes identifiées pour la synchronisation quotidienne future, non construites ce soir.** Deux API distinctes selon la nature de la donnée : l'API Sirene officielle (`api.insee.fr`, inscription séparée requise) pour l'identité/effectif via une requête par plage de dates (`dateDernierTraitementUniteLegale`) ; l'API différentielle du RNE/INPI (`registre-national-entreprises.inpi.fr/api/companies/diff` et `/api/bilans-saisis`) pour les formalités et les comptes annuels, toutes deux avec un curseur (`searchAfter`) pour contourner leur propre plafond de 10 000 résultats. **Statut.** Migration du 56 terminée et vérifiée (167 468 lignes, structure `ENT_`). Extraction du 29 en cours au moment de la rédaction ; 48 traité comme département témoin pour les tests (21 859 entreprises). Restent à traiter : 22 et 35 (Bretagne), puis 17 et 64 évoqués pour l'usage "déplacement personnel". `ENT_Communes` alimentée pour 56/48/29. La synchronisation quotidienne (INPI/INSEE) reste à concevoir et construire — rien engagé au-delà de l'identification des bons endpoints. Aucune ligne de code applicatif ASPIC touchée ce soir : tout le travail décrit ici vit hors du dépôt (base `ENTREPRISES` + script autonome), toujours volontairement tenu à l'écart de l'application elle-même. `` n'avance pas dans cette section (aucune ligne du dépôt applicatif ASPIC touchée) ; `` avance de 24 à 25 — nouvelle version **V1.23.25**. ## 26. Backfill historique des comptes annuels, dimensionnement disque national, et un incident sérieux (12-13 septembre 2026) **Origine.** Suite directe de la section 25 : les 4 départements bretons extraits, restait à peupler Phase3 avec l'historique complet des comptes annuels (2017 à aujourd'hui), pas seulement la dernière année déjà captée à l'extraction. **Traduire la liasse fiscale brute en CA/résultat net — le vrai travail de cette session.** L'endpoint INPI `/api/bilans-saisis` ne renvoie pas un CA/résultat net direct mais une liasse fiscale complète (codes CERFA type "FJ", "HN"...), dont la signification dépend du type de bilan (`codeTypeBilan` : C, S, K, AC, AS, B). Table de correspondance établie à partir de la documentation officielle INPI (v5, juin 2025) puis **vérifiée empiriquement sur un vrai bilan (EDF, SIREN 552081317)** pour confirmer la bonne colonne (m3 = exercice en cours quand elle existe, sinon m1). Bug détecté et corrigé en cours de route : une même entreprise dépose souvent **à la fois** ses comptes individuels (C) et consolidés de groupe (K) pour la même année — sans règle de priorité, l'un écrasait l'autre au hasard de l'ordre de traitement. Priorité retenue : toujours préférer les comptes propres de l'entité (C/AC/AS/S) à un chiffre de groupe consolidé (K), qui ne représente plus l'entreprise précise. Les bilans en confidentialité non publique ne sont jamais exploités, par respect du choix déclaré par l'entreprise. Script autonome : `src/scripts/inpi_bilans_backfill.py`, surnommé **BFH** ("backfill historique") dans les échanges avec Jean-Marc — désormais systématiquement enchaîné après `sirene_extract.py` pour tout nouveau département, sans qu'il ait à le redemander (Phase2 reste exclue de cet automatisme, elle demeure un traitement manuel à part). **Tables de pilotage ajoutées à la demande de Jean-Marc** : `ENT_Departements` (un département géré = une ligne, avec compteur d'entreprises mis en cache pour éviter des `COUNT(*)` répétés sur des tables qui grossissent) et `ENT_Config` (clé/valeur générique pour les réglages globaux, ex. date de la prochaine synchro quotidienne des comptes annuels, qui n'est pas filtrable par département). Remplace l'idée initiale de Claude (découvrir les départements via `SHOW TABLES`) — Jean-Marc a jugé une vraie table plus simple à interroger depuis ASPIC, avec raison. **Dimensionnement national anticipé par Jean-Marc, avant d'avoir mal.** Question posée de façon proactive : sachant qu'il y a ~8,5M d'entreprises en France (chiffre INSEE cité par Jean-Marc), la base tiendra-t-elle le choc ? Calcul fait sur les tailles réelles mesurées (~7,3 Ko/entreprise en moyenne sur 5 départements) : projection nationale ≈ 70 Go, soit 36-40% du disque du VPS (193 Go, 154 Go libres à ce moment) — un chiffre que Jean-Marc a justement qualifié de "pas négligeable", refusant de le balayer d'un revers de main. Jean-Marc a lui-même relevé que la région parisienne (75 : 484 011 entreprises, 92 : 265 707, chiffres INSEE vérifiés) serait un point chaud disproportionné, pas une simple extrapolation linéaire depuis la Bretagne. Solution appliquée : compression native InnoDB (`ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8`) sur la table Phase1 (dominée par le JSON brut de l'API, qui compresse très bien) — gain réel mesuré de **-60%** sur les 5 tables existantes, ramenant la projection nationale à ~28-30 Go (15% du disque). Intégré au gabarit de création de table de `sirene_extract.py`, donc acquis automatiquement pour tous les départements à venir sans y repenser. **Incident sérieux dans la nuit : le BFH a fait tomber le serveur en OOM.** Le script a été tué par le noyau après avoir atteint 9,33 Go de RAM — et le OOM killer a également tué **systemd lui-même** au passage (le serveur s'est remis seul, sans perte de service durable, 10 jours d'uptime conservés). Cause identifiée : la boucle de pagination par curseur (`searchAfter`) de l'appel `/api/bilans-saisis` n'avait aucun garde-fou — un lot bloqué (curseur qui n'avance plus, ou volume de résultats anormal pour un gros groupe) pouvait boucler en accumulant des résultats en mémoire indéfiniment, sans jamais lever d'erreur propre ni s'arrêter. Corrigé par un double garde-fou : plafond de 100 pages par lot, et détection explicite d'un curseur qui stagne (comparaison avec la valeur précédente). **Nouvelle règle de méthode actée pour la suite : tout lancement d'un script de récupération de données volumineuses doit désormais être encadré par `ulimit -v` (4 Go utilisé ici) avant le `nohup`, pour qu'un futur bug fasse planter le script, jamais le serveur entier.** Aucune perte de données : la conception en `UPSERT` (jamais un `INSERT` seul) fait que reprendre depuis zéro après un crash ne recrée aucun doublon, juste un peu de travail réseau redondant. **Statut.** BFH relancé avec succès après correctif (mémoire redescendue de plusieurs Go à 62 Mo au même point de progression — le vrai bug semble bien corrigé, pas seulement contenu par le plafond de sécurité). Jean-Marc parti se coucher avec la suite actée pour cette nuit, sans supervision : une fois le BFH du 56 terminé, extraction + BFH enchaînés pour 44, 49, 85, 17, 40, 64 et 65, chaque étape protégée par le même `ulimit`. Mise à jour du dépôt remise au lendemain par Jean-Marc lui-même, comme toujours. `` n'avance pas dans cette section (aucune ligne du dépôt applicatif ASPIC touchée — tout le travail vit dans `src/scripts/` et la base `ENTREPRISES`) ; `` avance de 25 à 26 — nouvelle version **V1.23.26**. ## 27. Statistiques par commune, premières esquisses de carte de prospection géographique, et un correctif de fond sur le repli NAF (13 septembre 2026) **Suite de la nuit du 12 au 13.** La chaîne sans supervision (44, 49, 85, 17, 40, 64, 65) s'est terminée sans incident, `ulimit -v` et garde-fou de pagination tenant leurs promesses. Une seconde chaîne a été lancée dans la foulée pour 31, 32, 33, 46, 47, 09, 13 et 66 (Occitanie/PACA), avec un décalage de départ pour ne jamais faire tourner deux extractions Sirene en même temps. **Nouveau champ `ENT_CodeCommune` sur Phase1**, backfillé sans nouvel appel API (déjà présent dans le JSON brut stocké de chaque entreprise) sur les 7 départements de la première chaîne — nécessaire pour la fonctionnalité suivante. **Statistiques par taille d'entreprise, par commune.** À la demande de Jean-Marc : cinq nouveaux champs sur `ENT_Communes` (`COM_EI`, `COM_TPE`, `COM_PME`, `COM_ETI`, `COM_GE`), alimentés par un script quotidien dédié (`ent_communes_stats.py`), pour que le futur module de recherche géographique n'ait jamais à compter en temps réel sur des tables Phase1 qui grossissent. Règle de classification : `ENT_CategorieEntreprise` prioritaire quand l'INSEE la renseigne (GE/ETI/PME) ; sinon répartition EI/TPE selon le premier chiffre de `ENT_NatureJuridique` (entrepreneur individuel = '1'). Deux bugs trouvés et corrigés avant mise en production : `SUM()` renvoie `NULL` (pas 0) sur un ensemble vide, faussant l'agrégat d'une commune sans aucune entreprise d'une catégorie — corrigé par `COALESCE(..., 0)` ; et surtout, une commune pouvait voir ses compteurs écrasés par un département qui ne la possède pas réellement (établissement secondaire présent dans la table Phase1 d'un département voisin) — corrigé en restreignant le calcul aux communes réellement rattachées au département traité via une jointure sur `ENT_Communes`, révélant au passage un conflit de collation (`utf8mb4_unicode_ci` vs `utf8mb4_0900_ai_ci`) entre tables créées à des moments différents, réglé par un `COLLATE` explicite dans la jointure. **Première brique d'écran : la carte de prospection par géographie personnelle**, idée actée en section 25 (l'isochrone IGN), construite ce jour sous forme de prototypes interactifs (Claude Artifacts) plutôt que dans l'application : une commune de départ au centre, les communes accessibles en 30 minutes de route autour (isochrone réel + position géographique relative, projection locale corrigée du cosinus de la latitude), chacune avec son temps de trajet réel (API IGN `itineraire`) et ses effectifs EI/TPE/PME/ETI/GE réels tirés de `ENT_Communes`. Trois itérations avec retour de Jean-Marc avant d'aboutir à une version jugée satisfaisante : espacement des cartes pour éviter le chevauchement (algorithme de répulsion par paires, position géographique réelle conservée via un point + ligne de rappel quand une carte est déplacée pour la lisibilité), puis remplacement de la navigation par ascenseur natif (peu fiable dans le rendu de la fenêtre d'Artifact à certains niveaux de zoom navigateur) par un cliquer-glisser JavaScript, au clic gauche **et** au clic droit — Jean-Marc ayant signalé une habitude de navigation au clic droit. Quatre versions produites : Lorient (démonstration initiale), Lanester (ville de résidence de Jean-Marc, test de cohérence des distances), puis Concarneau et Beuzec-Cap-Sizun (Finistère) à la demande de Jean-Marc pour deux amis, comme simple partage d'un lien — pas encore une fonctionnalité ASPIC, mais une preuve que la donnée collectée a une valeur de démonstration immédiate. **Correctif de fond sur le repli NAF à 3 niveaux — la vraie panne de la journée.** Le 3e niveau de repli (par code NAF précis), ajouté le 12 septembre pour débloquer Rennes (section 26 — un seul cas rencontré alors, section L), s'est révélé mal conçu à l'échelle : au lieu de ne tester que les codes NAF appartenant à la section en cours, il retestait les 732 codes en entier **à chaque section qui restait plafonnée**. Sur une grande ville où plusieurs sections dépassent le plafond simultanément (Toulouse : au moins 6 sections concernées), ce défaut a bloqué l'extraction du département 31 pendant plusieurs heures sans jamais planter ni progresser de façon visible — seule la répétition suspecte des mêmes codes (68.20A/68.20B, immobilier) à chaque section a permis de repérer le problème. Corrigé par une table de correspondance division→section NAF (standard, 21 sections, vérifiée exhaustive sur les 732 codes), limitant désormais le 3e niveau aux seuls codes réellement concernés par la section (6 codes pour la section L, contre 732 avant). Département 31 relancé depuis le début après correctif (pas de mécanisme de reprise par commune dans le script) : Toulouse traitée en quelques minutes au second passage, chaîne 2 poursuivie normalement. **Cap symbolique franchi en cours de journée : plus de 2 millions d'entreprises cumulées** (2 227 587 exactement, sur 15 départements traités, le 33 encore en cours) — 31 (Haute-Garonne, avec Toulouse) est à lui seul le département le plus lourd traité jusqu'ici (312 359 entreprises). **Premières réflexions sur la refonte du module Contacts, notées mais pas construites.** Jean-Marc a acté un changement de sens par rapport à la conception initiale des contacts : le lien entreprise↔contact ne sera plus exclu multiple (une entreprise peut avoir plusieurs contacts, un contact peut être lié à plusieurs entreprises), et la qualification (statut, score, canal) portera sur l'**entreprise**, pas sur le contact — la fiche contact ne conservant de l'entreprise que ce qui sert à garder le lien. Trois étapes de prospection distinguées : qualification des entreprises sélectionnées, recherche du ou des contacts, démarche commerciale classique — avec la précision que toute prospection ne partira pas nécessairement d'une qualification d'entreprise (d'autres approches resteront possibles). En préparant les écrans, Jean-Marc a demandé le détail du contenu du JSON brut Sirene stocké (structure décrite : `siege`, `dirigeants`, `finances`, `complements`) et relevé l'absence du capital social, confirmée après vérification (absent de cette API, disponible seulement côté INPI RNE, jamais interrogé à ce jour) — Jean-Marc a d'ores et déjà indiqué que ce champ relèverait de la qualification locale (donc jamais mutualisée), cohérent avec la séparation Phase1/Phase2 actée section 25. Sujet remis à plus tard dans son ensemble, quand ce chantier sera formellement ouvert. **Statut.** 15 départements avec extraction et historique financier complets (17, 22, 29, 35, 40, 44, 48, 49, 56, 64, 65, 85 + 31, 32 achevés dans la chaîne 2, 33 en cours). Restent 46, 47, 09, 13, 66 en extraction puis BFH pour l'ensemble des 8 nouveaux départements. `ent_communes_stats.py` opérationnel mais pas encore automatisé quotidiennement (à brancher sur n8n avec la synchronisation incrémentale, toujours non construite). Quatre prototypes de carte de prospection publiés en Artifacts, partagés par Jean-Marc à deux amis — aucune intégration à l'application elle-même. `` n'avance pas dans cette section (tout le travail vit dans `src/scripts/`, la base `ENTREPRISES`, et des prototypes hors dépôt) ; `` avance de 26 à 27 — nouvelle version **V1.23.27**. ## 28. Suspension du BFH, découverte des arrondissements PLM, extraction France entière et refonte de la feuille de route ENTREPRISES (14-15 septembre 2026) **Deux bugs de fond supplémentaires trouvés sur le BFH, le lendemain du précédent.** Le curseur de pagination de `bilans-saisis` utilisait le SIREN du dernier résultat comme `searchAfter` — or un SIREN a souvent plusieurs bilans (plusieurs années), donc revient plusieurs fois dans les résultats ; le garde-fou anti-boucle de la veille prenait ça à tort pour un blocage et abandonnait le lot en cours, perdant des bilans déjà partiellement récupérés (~14% des lots du département 31 touchés). Vérifié empiriquement que le champ `id` (identifiant unique par bilan, présent dans chaque réponse) donne une pagination propre sans doublon — corrigé. Puis, une fois relancé, l'API INPI a commencé à renvoyer des 401 (jeton expiré en cours d'exécution) après plusieurs heures d'appels continus — le script retentait 8 fois avec le même jeton mort, ce qui ne pouvait jamais réussir. Corrigé par une reconnexion automatique (`auth` devient un dict mutable partagé, se régénère tout seul sur un 401). **Puis un vrai mur, cette fois non contournable par du code : un quota INPI dépassé** (`"errorCode":"quota_exceeded"`, `"webserviceCode":"QUOTA_SERVICE"`, confirmé par inspection directe du corps de réponse HTTP 429). Contrairement à une limitation de débit passagère, retenter ne sert à rien tant que le quota ne s'est pas régénéré (vraisemblablement journalier). Correctif appliqué par prudence (une `QuotaExceededError` dédiée fait interrompre immédiatement tout le traitement plutôt que de s'acharner lot après lot), mais **décision de Jean-Marc, plus radicale et plus sage : suspendre entièrement le BFH pour l'instant**, risque de bannissement du compte INPI jugé disproportionné par rapport au bénéfice — l'historique financier pourra être rattrapé "petit à petit dans les mois à venir", l'essentiel étant d'abord de disposer de l'identité de toutes les entreprises françaises pour commencer à travailler sur la structure des données et les écrans. **Découverte majeure et indépendante, sur l'extraction Sirene elle-même : Paris, Lyon et Marseille (PLM) étaient massivement sous-captées.** Repéré à l'œil par Jean-Marc, qui a trouvé étonnant que le département 33 (Gironde, 416 980 entreprises) dépasse le 13 (Bouches-du-Rhône, alors 330 238) alors que Marseille est économiquement plus lourde que Bordeaux. Vérifié : dans les données Sirene, une entreprise marseillaise n'est quasiment jamais rattachée au code commune englobant (13055, ~10 résultats seulement) mais à son arrondissement (13201 à 13216) — or la liste des communes utilisée pour l'extraction ne renvoyait que le code englobant, jamais les 16 arrondissements, chacun pourtant déjà plafonné ou proche du plafond de 10 000 à lui seul. Corrigé (`sirene_extract.py` détecte désormais les trois villes à arrondissements et interroge `geo.api.gouv.fr?type=arrondissement-municipal` à la place du code englobant), `ENT_Communes` corrigée à la main pour le 13 (13055 supprimée, ses 16 arrondissements ajoutés), réextraction du 13 replanifiée en fin de chaîne. Paris et Lyon n'avaient pas encore été traités à ce stade, donc le correctif s'applique nativement dès leur premier passage. **Décision de méthode pour la suite : terminer l'aspiration avec la méthode Sirene actuelle jusqu'au bout, sans la mélanger à une autre source en cours de route** (pour ne pas risquer d'hétérogénéiser les données), **mais reconcevoir entièrement la stratégie de mise à jour a posteriori**. Chaîne dédiée relancée (extraction seule, aucun appel INPI) pour l'intégralité de la France restante — 81 départements, métropole **et DOM-TOM inclus** (Jean-Marc : "Ne te limite pas à la métropole ! J'ai des amis à la Réunion, j'y passerai bien volontiers du temps !"), La Réunion placée en tête de liste pour cette raison personnelle. Rythme observé : environ 1h/département pour un département rural, plusieurs heures pour une grande ville nécessitant le repli NAF (Nice : 3h05). **Statut à la rédaction : 55 départements extraits, 7 036 958 entreprises** (~83% de l'estimation nationale de 8,5M) — la trajectoire confirme l'hypothèse de Jean-Marc que les 24 premiers départements traités (Bretagne puis Occitanie/PACA) étaient disproportionnellement denses, et que la moyenne va continuer de se rapprocher du national à mesure que les départements ruraux restants sont traités. **Vérification croisée de plusieurs ratios avec Jean-Marc, à chaque fois confirmée par de vraies mesures plutôt qu'une simple extrapolation théorique** : le nombre d'entreprises (dépassement des 50% national constaté en direct) ; l'espace disque (10,69 Go réels pour 3,63M entreprises à ce moment, soit ~3 133 octets/entreprise compressé, projection nationale ~26,6 Go — cohérente avec l'estimation théorique de la section 26) ; et la proportion d'entrepreneurs individuels, mesurée sur les données déjà collectées plutôt que supposée : **41,3% d'EI (sans capital social), 58,7% de non-EI**, dont 3,27M déjà catégorisées GE/ETI/PME par l'INSEE. **Piste ouverte par un ami de Jean-Marc, consultant senior, vérifiée et confirmée réelle : l'INPI met à disposition un export en masse du RNE, en FTP/SFTP, séparé de l'API paginée.** Recherche effectuée (dont un projet open-source `etalab/rncs_worker_api_entreprise` en confirmant l'usage réel) : structure stock + flux quotidien, format CSV, capital social explicitement présent comme champ. Demande d'accès faite par Jean-Marc le 15 septembre, accordée le jour même. Connexion testée (lecture seule) : `ftp://www.inpi.net` (FTP simple, pas du vrai SFTP malgré l'intitulé de la demande — source probable de la première tentative infructueuse de Jean-Marc sous FileZilla, configuré en SFTP). Quatre fichiers trouvés à la racine, deux jeux (formalités/comptes annuels) × deux versions chacun, aucun flux quotidien visible à ce niveau : `stock_RNE_formalites_NIVEAU1_20260320_1400.zip` (15,1 Go, mars 2026 — vraisemblablement la source du capital social), `stock_RNE_comptes_annuels_NIVEAU1_20260320_1400.zip` (4,3 Go). Dernier stock à 6 mois d'écart de la date du jour — jugé acceptable pour le capital social (donnée peu volatile) mais insuffisant en l'état pour les comptes annuels. Identifiants stockés dans `.env` (`INPI_RNE_FTP_*`), rien téléchargé, sujet à approfondir sans urgence. **Réouverture et correction consciente d'une décision antérieure sur le capital social.** Jean-Marc était revenu sur ce qu'il avait dit trois jours plus tôt (section 27) : le capital social avait été classé à tort comme donnée de qualification privée par compte, alors que c'est une donnée factuelle de l'entreprise au même titre que le NAF ou l'effectif — elle doit vivre dans `ENTREPRISES`, mutualisée. Jean-Marc a également tranché explicitement pour une exception assumée au principe "jamais d'écriture dans `ENTREPRISES` déclenchée par un utilisateur" : la mise à jour du capital social pourra être initiée par une action utilisateur, précisément parce que c'est une information structurante — la conception du mécanisme (file d'attente, appel synchrone, etc.) reste ouverte, dépendante de limites de l'API RNE non encore connues (débit, temps de réponse), sans urgence vu le lancement commercial d'ASPIC visé "seulement" début 2028. **Feuille de route formelle déposée par Jean-Marc** (`src/fdr/1. ENTREPRISES V1.0`), première utilisation de ce nouveau circuit de transmission (dépôt de fichier dans un répertoire dédié plutôt que description en conversation). Relecture complète effectuée à la demande explicite de Jean-Marc ("pour avoir ton retour... pas pour passer à l'action"). Points de retour marquants : découverte, en vérifiant une question de Jean-Marc sur les champs JSON, que `matching_etablissements[]` (jamais exploité) contient probablement l'adresse propre de chaque établissement secondaire ayant fait matcher une recherche — invalidant l'hypothèse de départ de Jean-Marc qu'on ne pourrait pas la connaître, et permettant potentiellement de retrouver un établissement secondaire par ville de recherche ; ~30% des entreprises ont plusieurs dirigeants dans le JSON, un seul capturé actuellement ; signalement d'une collision de nommage évitée de justesse (la feuille de route proposait de recycler le nom "Phase2", déjà porteur d'un sens différent et déjà documenté — Jean-Marc a tranché : `Phase2` disparaît purement et simplement de `ENTREPRISES`, son rôle originel renaît dans la base de chaque utilisateur sous un nom encore provisoire, `ASP_ENTQualif`). **Clarification du trombinoscope des collaborateurs ASPIC, à l'occasion d'une coquille apparente.** La feuille de route mentionnait "la voix de Viktor" pour une future compétence de qualification — pas une erreur : les cinq collaborateurs nommés d'ASPIC sont **Matilda, Viktor, Sophia, Léon et Nikita**, et Jean-Marc a confirmé une répartition claire pour au moins deux d'entre eux : **Léon** porte la gestion (dont la garde d'`ENTREPRISES`), **Viktor** porte le commercial (dont la future qualification et son suivi temps/coût/réussite). Viktor n'a pas encore d'interface vocale prévue, "mais pourquoi pas quand je n'aurai plus que ça à faire". **Statut.** BFH suspendu partout, à reprendre progressivement et sans urgence dans les mois à venir, avec une stratégie de mise à jour entièrement à reconcevoir (API paginée vs flux RNE en masse). Extraction Sirene seule en cours sans interruption depuis le 14 septembre, 55 départements sur 101 (métropole + DOM-TOM), 7 036 958 entreprises. Feuille de route ENTREPRISES V1.0 relue et commentée, pas encore amendée par Jean-Marc (en cours). Accès FTP RNE obtenu et testé en lecture seule, non exploité. `` n'avance pas dans cette section (deux scripts modifiés — `inpi_bilans_backfill.py`, `sirene_extract.py` — mais toujours hors du dépôt applicatif ASPIC lui-même) ; `` avance de 27 à 28 — nouvelle version **V1.23.28**. ## 29. Recalibrage à 13,4M d'entreprises, doublons de filiales confirmés, et institutionnalisation des feuilles de route (16 septembre 2026) **Nouvelle méthode de travail actée pour cadrer les gros chantiers : les feuilles de route numérotées.** Jean-Marc, fatigué par la "navigation à vue" (peur constante d'oublier un point déjà discuté), a mis en place un circuit formel : il rédige une feuille de route par grand chantier, la dépose en PDF (puis `.docx`) dans un nouveau répertoire `src/fdr`, numérotée `1` à `11` selon le chantier (1. Évolutions BDD ENTREPRISES, 2. Gestion des contacts, 3. Sélection des Entreprises, 4 à 11 pas encore communiqués). Claude Code la lit intégralement, donne un retour écrit — jamais d'implémentation à ce stade — et, règle rendue systématique en cours de journée, **intègre désormais toujours ses commentaires dans une nouvelle version du fichier** plutôt que de les laisser vivre uniquement dans la conversation ("je pourrais décider de supprimer, mais je ne veux pas risquer de perdre un commentaire"). Outillage installé pour l'occasion sur le VPS (`python3 -m pip install --break-system-packages python-docx fpdf2 openpyxl` — pip lui-même absent, installé via `apt-get install python3-pip`) : génération de `.docx` éditables (Jean-Marc a explicitement demandé l'arrêt de la génération PDF, "je ne peux rien en faire"), lecture de maquettes d'écran Excel (`openpyxl`, testé avec succès sur une première maquette de fiche contact). Deux bugs de génération trouvés et corrigés en cours de route, tous deux désormais documentés pour ne pas être réintroduits : accents français supprimés par réflexe d'un ancien évitement d'encodage devenu inutile, et titre du document supprimé par erreur du `.docx` en corrigeant un doublon qui n'existait que côté PDF (les deux générateurs ne partagent pas la même logique d'en-tête). **Feuille de route "Évolutions BDD ENTREPRISES" (ex-ENTREPRISES) itérée de V1 à V6.** Relecture point par point à chaque version, jamais d'implémentation. Découverte notable en répondant à une question de Jean-Marc sur les champs JSON : `matching_etablissements[]` contient un booléen `est_siege` directement exploitable pour distinguer siège et établissement secondaire, sans déduction ni colonne enum à maintenir — et ce même tableau donne probablement l'adresse propre de chaque établissement secondaire, invalidant l'hypothèse initiale de Jean-Marc qu'on ne pourrait pas la connaître. **Vérification empirique déterminante, demandée explicitement par Jean-Marc pour trancher un doute méthodologique** (il voulait s'assurer que la preuve ne reposait pas sur le champ adresse, déjà connu comme erroné pour les filiales) : comparaison réelle entre `Entreprises35Phase1` et `Entreprises44Phase1`, confirmant **7 802 SIREN présents comme ligne physique dans les deux tables à la fois** (exemple vérifié : "G2 (THE BRITISH CASHMERE)") — preuve reposant sur l'existence même de la ligne dans chaque table indépendante, pas sur son contenu. Conclusion actée par Jean-Marc : le stockage des filiales devra changer en profondeur pour éliminer ce doublon structurel, sujet noté pour la prochaine feuille de route plutôt que traité dans l'urgence. Autres décisions actées au fil des versions : `Phase2` disparaît purement et simplement de `ENTREPRISES` (son rôle renaît dans la base de chaque compte utilisateur, nom pressenti `ASP_ENTQualif`) ; le JSON brut migre vers une nouvelle table dédiée (`Phase4`, jamais "Phase2" pour éviter la collision de sens) ; ~30% des entreprises ont plusieurs dirigeants dans le JSON (un seul capturé actuellement) mais ces dirigeants sont rattachés à l'entreprise entière, pas à un établissement précis — limite à connaître avant de concevoir la future table des dirigeants. **Nouvelle feuille de route "3. Sélection des Entreprises" déposée et itérée (V1 à V5).** Pose les bases du futur module de sélection multicritère (géographie, secteur, effectif, date de création...), explicitement bloqué tant que la structure d'`ENTREPRISES` n'est pas définitive. Points de retour marquants : le mécanisme "critères extensibles sans modifier le code" que souhaite Jean-Marc n'est pas à inventer, c'est le même patron déjà construit pour ASPIC (règles et consignes en langage naturel, section 15/17) ; l'hypothèse de Claude sur les dépendances entre critères (uniquement au sein de la hiérarchie géographique, pas entre facettes indépendantes) confirmée indépendamment par Jean-Marc, avec la nuance qu'il faudra vérifier à l'usage pour les EI/associations ; question ouverte sur le stockage des quotas anti-abus (MIRADOR, dont le rôle actuel se limiterait à l'étendre, vs la base propre de chaque compte). **Recalibrage majeur de la cible nationale : 8,5M devient 13,4M.** Jean-Marc a trouvé un site tiers (nouvelles-entreprises.com, republication commerciale de données SIRENE) annonçant 13 458 259 "entreprises actives au registre SIRENE (établissements sièges)", recalculé chaque nuit. Écart expliqué et non contradictoire avec le chiffre de 8,5M utilisé jusque-là : l'INSEE publie aussi un agrégat statistique "entreprises" qui **regroupe les filiales d'un même groupe en une seule entité** — notre extraction, elle, dédoublonne par SIREN (unité légale), pas par ce regroupement statistique, donc sa cible réelle de convergence est bien plus proche de 13,4M. Projection disque recalculée sur mesure réelle (28,14 Go pour 8,7M entreprises à ce moment, soit 3 473 octets/entreprise compressé) : **~43,5 Go pour 13,4M**, toujours très confortable (~22-23% du disque du VPS). Vérification annexe : Bitdefender a signalé une activité suspecte sur ce même site tiers (`nouvelles-entreprises.com`) pendant que Jean-Marc le consultait — analysé et relativisé (le chemin `_nuxt/builds/latest.json` est un fichier technique standard et inoffensif du framework Nuxt.js, l'alerte provient plus probablement du `http://` non chiffré de l'URL) ; onglet fermé par précaution, sans lien avec ASPIC. **Extraction Sirene poursuivie sans interruption.** Lyon (69) traité avec succès grâce au correctif arrondissements de la section 28 : **506 425 entreprises**, le plus gros département à ce jour, confirmant en conditions réelles que le correctif tient la charge (ex. Lyon 1er arrondissement seul : 17 781 entreprises, très supérieur à ce que le code englobant aurait donné). **Statut à la rédaction : 74 départements sur 101, 9 855 993 entreprises** (~74% de la nouvelle cible à 13,4M) — Paris et le reste de l'Île-de-France restent à traiter, plus la réextraction du 13 (Marseille) en toute fin de chaîne. **Clarifications de fond, hors chantier ENTREPRISES, à la demande de Jean-Marc.** Distinction actée entre l'abonnement Claude Max personnel de Jean-Marc (couvre son usage interactif, pas l'API) et l'API Anthropic que consommeront les utilisateurs d'ASPIC (compte développeur séparé, facturation à l'usage) — point de confusion corrigé avant qu'il n'affecte un choix commercial. Piste "clé API par utilisateur" explorée puis écartée par Jean-Marc lui-même (confusion avec une autre idée) au profit de **Claude Cowork côté utilisateur final pour les fonctionnalités réseaux sociaux** — logique validée : Cowork tourne sur l'abonnement personnel de l'utilisateur, donc hors du budget API d'ASPIC, cohérent avec le souci de marge de Jean-Marc. Jean-Marc a lui-même noté que son abandon passé de Cowork (écriture bloquée hors `C:\`, dépôt Git en lecture seule) ne s'applique pas au même besoin : ce qu'il faisait avec Cowork était de l'administration serveur exigeant un accès direct (d'où son usage actuel de Claude Code), alors que le besoin envisagé pour les utilisateurs ASPIC est bureautique/local. **Statut.** Extraction Sirene : 74/101 départements, 9 855 993 entreprises, en cours sans incident. BFH toujours suspendu (section 28). Deux feuilles de route actives dans `src/fdr` : "1. Évolutions BDD ENTREPRISES" (V6, renommée par Jean-Marc) et "3. Sélection des Entreprises" (V5) — aucune des deux encore validée pour passage à l'implémentation. Accès FTP RNE toujours inexploité. Collaborateurs ASPIC (Matilda, Viktor, Sophia, Léon, Nikita) et leurs rôles connus consignés en mémoire pour la suite. `` n'avance pas dans cette section (feuilles de route et scripts d'outillage PDF/docx/xlsx vivent hors du dépôt applicatif ASPIC) ; `` avance de 28 à 29 — nouvelle version **V1.23.29**. ## 30. Incident de parallélisme sur l'extraction, naissance du projet entreprises.bzh, et mesure réelle du double-comptage (17 septembre 2026) **Nouvel incident, cette fois provoqué par Claude Code lui-même.** En tentant de rattraper le département 74 (interrompu la veille par un aléa réseau), un script de reprise a été lancé **en parallèle** de la chaîne principale — erreur de jugement, l'hypothèse que `recherche-entreprises.api.gouv.fr` n'avait jamais montré de limite s'est révélée fausse sous charge concurrente. Les deux traitements simultanés ont fini par saturer l'API (HTTP 429 soutenu), faisant planter en cascade **75 (Paris), 76 et 77** en plus du 74 déjà en cours de reprise. Aucune perte de données (conception UPSERT), mais quatre départements incomplets. Corrigé sur deux plans : `http_get_json()` dans `sirene_extract.py` durci (retries avec backoff exponentiel sur 429 et respect de `Retry-After`, rattrapage de `http.client.HTTPException`/`ConnectionError` en plus de `URLError` — un `RemoteDisconnected` n'était pas rattrapé avant, cause du tout premier plantage du 74) ; et surtout, **plus aucun traitement en parallèle désormais, toujours strictement séquentiel**, leçon actée en mémoire. Une reprise séquentielle de 74/75/76/77 a été programmée pour démarrer automatiquement une fois la chaîne principale entièrement terminée, sans chevauchement possible. Un second incident, sans lien, a suivi le 17 au soir : le département 88 a échoué sur un verrou MySQL (`Lock wait timeout`), probablement lié à la charge d'un calcul de dédoublonnage lancé en parallèle par Claude Code — ajouté à la liste des départements à reprendre. **Naissance d'un projet dérivé : `entreprises.bzh`.** Une observation de Jean-Marc sur le modèle économique de nouvelles-entreprises.com (revenu réel sur l'envoi de courrier postal, pas l'abonnement) a fait germer l'idée d'un site indépendant, construit sur la même base `ENTREPRISES`, proposant l'accès aux données d'entreprises via une méthode de recherche originale (isochrone/temps de trajet réel, pas un simple rayon en km — confusion de vocabulaire de Jean-Marc corrigée en cours de route). Jean-Marc a demandé à une autre session Claude un dossier d'analyse de marché complet (tarifs, structure de facturation, contraintes légales) — document de grande qualité, sourcé et prudent sur ses propres limites, déposé et relu en détail. Trouvailles marquantes : **aucun concurrent recensé ne combine fraîcheur quotidienne et sélection géographique fine** (Smappen s'en approche mais avec une base trimestrielle) — le créneau existe réellement. Structure de facturation suggérée : pas de prix à la ligne (course au prix bas déjà occupée), mais deux prestations distinctes, extraction brute alignée marché et "étude de zone" au forfait, seule cette dernière valorisant réellement l'outil. Point juridique découvert en cours de lecture, avec impact technique direct : depuis mars 2023, le statut "non-diffusible" est remplacé par un statut **"P" (diffusion partielle)**, à exclure de toute redistribution commerciale — or `statut_diffusion` n'est capturé nulle part comme colonne exploitable dans `ENTREPRISES` aujourd'hui, seulement noyé dans le JSON brut. Décision actée : ne pas modifier l'extraction en cours (au-delà de 80% de la France) pour ce champ, le rattacher au grand remodelage de Phase1 déjà prévu. **Objectif du projet précisé par Jean-Marc, plus riche qu'une simple opportunité commerciale.** Visée : mise en ligne à la création de la société (**début 2027**, soit environ un an avant le lancement commercial d'ASPIC), avec cinq finalités explicites — avoir quelque chose en vente dès le début d'activité, s'affronter concrètement à une solution de paiement en ligne, à la facturation électronique, se pousser à communiquer sur les réseaux sociaux via les fonctionnalités mêmes d'ASPIC, et dégager un peu de trésorerie pour financer un futur serveur OVH dédié (non mutualisé). Coût d'entrée dérisoire : le seul nom de domaine, `entreprises.bzh`, acquis dans la foulée. Jean-Marc reste "à l'affût comme un chien de chasse" si un vrai modèle économique se dessinait, sans en faire une condition. Le module de sélection sera construit une fois pour ce site puis répliqué dans ASPIC — et Jean-Marc envisage déjà l'argument marketing du jour où ASPIC sortira : ces fonctionnalités y seront incluses gratuitement. **Discussion approfondie sur l'enrichissement de contact via LinkedIn, questionnement personnel de Jean-Marc sur l'exposition légale.** Un partenaire commercial de Jean-Marc a vanté l'usage quotidien de Waalaxy sans jamais avoir été banni — argument que Jean-Marc a lui-même écarté par une analogie efficace (rouler à 100 km/h sur une route de campagne sans jamais croiser de gendarme n'en fait pas une pratique sûre). Question soulevée par Jean-Marc : LinkedIn tolérerait-il tacitement ce type d'usage dans une mesure raisonnable ? Réponse nuancée apportée : LinkedIn a un historique documenté de poursuites actives contre des **éditeurs** d'outils d'automatisation (affaire hiQ Labs, mises en demeure), même si la détection au niveau utilisateur individuel reste probabiliste — donc la distinction pertinente pour Jean-Marc n'est pas "combien de temps avant d'être banni" mais "éditeur vs utilisateur isolé", un éditeur étant une cible bien plus exposée. Piste connexe soulevée par Jean-Marc et laissée ouverte, explicitement qualifiée de "borderline" par lui-même : faire réaliser la qualification via Claude Cowork en local chez l'utilisateur plutôt qu'un scraping centralisé — analysé comme une **dilution** du risque (compte individuel, détection plus difficile à grande échelle) mais pas une **élimination** de sa nature (toujours hors CGU si l'extraction reste automatisée), avec la même question de responsabilité d'éditeur si la fonctionnalité était packagée comme telle. **Mesure réelle du double-comptage inter-départements, chiffrée pour la première fois.** Calcul `COUNT(DISTINCT SIREN)` sur l'ensemble des tables Phase1 existantes : **12 331 573 lignes brutes, 11 142 436 SIREN réellement distincts, soit 1 189 137 doublons (9,6%)** — cohérent avec la découverte de la section 29 (35 vs 44). Poids disque correspondant : ~4,18 Go sur les 43,33 Go actuels de Phase1, présenté comme plafond théorique (le futur modèle allégera ces lignes plutôt que de les supprimer, l'info des établissements secondaires restant voulue). Conséquence rassurante sur la question "va-t-on dépasser 13,4M ?" : le total réellement distinct progresse normalement, la marge restante (Île-de-France complète, Marseille, Corse, DOM-TOM) ajoutera du vrai volume, pas seulement du doublon. **Feuilles de route ENTREPRISES et Sélection des Entreprises, nouvelles versions.** "1. Évolutions BDD ENTREPRISES" passée en V7 (le point statut "P" y a été ajouté). "3. Sélection des Entreprises" largement étoffée par Jean-Marc (V6) : le projet devient l'épine dorsale d'`entreprises.bzh`, méthodes de recherche listées, trois premières briques d'écran détaillées (avertissement RGPD, localisation géographique, type d'entreprise) accompagnées de leurs maquettes Excel. Relecture complète, correction actée (rayon en km → temps de trajet), confirmation de la sélection géographique limitée à une valeur unique par niveau (région/département/ville), passée en V7 avec les retours intégrés. Deux bugs supplémentaires de génération `.docx` trouvés et corrigés : langue par défaut du document (anglais au lieu de français, `w:lang` absent du style Normal) et titre manquant sur "Sélection des Entreprises" (même bug que la section 29 sur ENTREPRISES, pas encore appliqué à ce fichier-là). **Statut.** Extraction Sirene : reste l'Île-de-France (91 à 95), la Corse, les DOM-TOM restants (971/972/973/976) et le 13 (Marseille) dans la chaîne principale, puis une reprise séquentielle de 74/75/76/77/88. Fin réaliste estimée pour le week-end du 19-20 septembre, largement avant l'indisponibilité de Jean-Marc le lundi 21 — reprise du chantier de restructuration ENTREPRISES prévue mardi ou mercredi. BFH toujours suspendu (section 28). Accès FTP RNE toujours inexploité. Projet `entreprises.bzh` acté, domaine acquis, encore au stade de réflexion sur les écrans. `` n'avance pas dans cette section (deux scripts modifiés — `sirene_extract.py` durci — et outillage de feuilles de route, toujours hors du dépôt applicatif ASPIC) ; `` avance de 29 à 30 — nouvelle version **V1.23.30**. ## 31. Alerte disque serveur — 79 Go de binlogs MySQL jamais purgés (18 septembre 2026) **Alerte remontée par Jean-Marc** : 160 Go occupés sur 193 Go (84%), sans lien apparent avec l'avancement de l'extraction. Diagnostic mené avec Claude Code : la base `ENTREPRISES` elle-même ne pèse que 52 Go, croissance normale et attendue vu le volume actuel (~13M lignes). Le vrai responsable : **79 Go de journaux binaires MySQL (binlogs) accumulés dans 76 fichiers sur l'instance `mysql2`**, jamais purgés. Cause identifiée, pas une erreur de configuration à proprement parler : la purge automatique était bien active (`binlog_expire_logs_auto_purge=ON`), mais réglée à 30 jours de rétention — un réglage raisonnable pour l'usage CRM habituel, disproportionné face au volume d'écriture exceptionnel généré par une semaine d'extraction intensive (le chantier ayant commencé il y a moins de 30 jours, rien n'avait encore pu être purgé automatiquement). **Vérifié avant toute action** : aucune réplication ne dépend de ces binlogs (`SHOW REPLICAS` vide) — purge sans risque pour l'intégrité des données. Un premier essai (`PURGE BINARY LOGS`) a été bloqué par le classificateur de sécurité du mode auto de Claude Code, qui l'a signalé comme une possible altération de journaux d'audit — un principe de précaution générique s'appliquant même à un cas légitime. Plutôt que de chercher un contournement, Claude Code a exposé clairement la situation et les deux options à Jean-Marc (exécuter lui-même la commande, ou autoriser explicitement l'action) ; Jean-Marc a choisi d'autoriser, la commande a alors été acceptée et exécutée sans encombre. **Résultat : 79 Go libérés, disque ramené de 84% à 43% d'occupation** (161 Go → 83 Go utilisés sur 193 Go). Rétention réduite temporairement à 3 jours (`binlog_expire_logs_seconds=259200`) le temps que dure l'extraction intensive, à remettre à 30 jours une fois celle-ci terminée si c'est le réglage voulu en régime de croisière. **Suite envisagée par Jean-Marc** : intégrer une surveillance de l'espace disque au BackOffice d'ASPIC (déjà home des outils internes — voir section 32 mentionnée dans le journal Index pour le BackOffice existant) plutôt que de compter sur une vérification manuelle occasionnelle. Raison donnée : la console Hostinger elle-même n'affiche pas l'occupation disque en temps réel (données remontées avec un délai notable), d'où l'intérêt d'un indicateur suivi en direct côté ASPIC plutôt que de dépendre de ce tableau de bord tiers. Idée notée, pas encore développée. `` n'avance pas dans cette section (intervention d'infrastructure sur le serveur, hors dépôt applicatif ASPIC) ; `` avance de 30 à 31 — nouvelle version **V1.23.31**. ## 32. Bug Corse identifié et corrigé, deux départements orphelins retrouvés, et nom définitif d'entreprises.bzh trouvé — entreprizh.bzh (18-19 septembre 2026) **Un troisième "monstre" découvert dans la dernière ligne droite de l'extraction : la Corse (2A/2B) revenait systématiquement à 0 entreprise, sans aucune erreur.** En creusant à la demande de Jean-Marc ("chez moi les tables sont vides"), diagnostic isolé et vérifié empiriquement par appels directs à l'API : le paramètre `code_commune` de `recherche-entreprises.api.gouv.fr` échoue silencieusement (0 résultat, HTTP 200, aucune erreur) dès qu'il reçoit un code commune alphanumérique (`2A004`, `2B033`...), alors qu'un code numérique classique (`01004`) fonctionne normalement — bug propre à l'API officielle, pas au script. La Corse est le seul territoire français dont les codes commune INSEE ne sont pas purement numériques, ce qui explique pourquoi ce cas n'était jamais apparu ailleurs. Le paramètre `departement` de la même API, lui, fonctionne correctement même pour `2A`/`2B`. Corrigé dans `sirene_extract.py` : nouvelle fonction générique `fetch_entreprises_for_filter()` (factorisée depuis l'ancienne `fetch_commune_entreprises()`, même cascade de repli section NAF → code NAF précis), et `fetch_departement_entreprises_direct()` qui interroge le département entier d'un coup pour tout code non purement numérique — `run_department()` bascule automatiquement sur ce mode via `dep.isdigit()`. **Deux départements orphelins supplémentaires retrouvés en vérifiant l'état réel de `ENT_Departements` avant de répondre à une question de Jean-Marc sur le total nationale.** Le **88 (Vosges)**, planté sur le verrou MySQL déjà repéré le 17 septembre (section 30), n'avait en fait jamais été réintégré dans le script de reprise malgré l'intention notée à l'époque — 33 457 lignes partielles en base, aucune ligne dans `ENT_Departements`. Le **48 (Lozère)**, découverte inédite, avait 21 859 entreprises déjà correctement extraites mais aucune ligne finale écrite (interruption juste avant cette dernière étape, cause non identifiée, sans doute un arrêt de processus isolé antérieur) — n'était dans aucune file d'attente. File de reprise (`/tmp/redo_74_75_76_77.sh`) mise à jour et relancée avec la liste complète : **74, 75, 76, 77, 88, 2A, 2B, 48**, toujours strictement séquentielle derrière la fin de la chaîne principale (13/Marseille, dernier département de cette dernière). **Total national fait le point à la demande de Jean-Marc, chiffré précisément.** 94 départements bien terminés et fiables : **13 088 450 entreprises**. Les 9 restants (13 en cours + les 8 de la file de reprise) totalisaient à cet instant ~1,51M de lignes déjà en base mais partielles pour la plupart — notamment 76 et 77, très en dessous de ce qu'ils devraient contenir. Confirmation chiffrée d'une intuition de Jean-Marc : Paris (75) affichait déjà 831 979 entreprises avant même la fin de sa reprise, proche du million pressenti. **Exploration visuelle du logo (détecteur de métaux/pépite) refermée pour l'instant, sans aboutir.** Jean-Marc a itéré des dizaines de fois avec l'outil Pippit AI sur une variante ajoutant des traces de balayage au sol, jusqu'à ce que l'outil lui-même signale son incapacité à retoucher précisément (absence de calques, dérive cumulative après trop d'itérations). Une tentative de Claude Code de proposer une alternative vectorielle (SVG, deux versions publiées en Artifact) a été jugée trop abstraite/schématique par rapport au rendu quasi-photo recherché — écartée. Piste de sortie identifiée mais reportée par Jean-Marc à une prochaine session (fatigue du sujet ce soir-là) : retoucher manuellement l'image déjà quasi satisfaisante dans un éditeur à calques (Photopea suggéré, gratuit, en ligne) plutôt que de continuer à batailler avec la génération IA — le changement demandé (supprimer une ligne, limiter le nombre de traces) est une retouche localisée sur fond presque uni, largement à la portée d'un éditeur classique. **Recherche du nom de domaine d'entreprises.bzh reprise et closes après plusieurs allers-retours, tous vérifiés avant achat conformément au principe explicite de Jean-Marc ("éviter les problèmes plutôt que devoir les gérer", répété ce soir-là).** `prospecter.bzh`, pourtant validé une première fois, écarté après vérification INPI : une marque française active **"PROSPECTER"** (FR4532717) existe, détenue par **TESSI**, déposée en classe 35 (publicité, gestion commerciale, télémarketing, acquisition de données) — recoupement direct avec l'activité visée, risque jugé trop sérieux malgré la nature partiellement descriptive du mot. `fichiers-prospects.fr`/`.com`, repérés disponibles par Jean-Marc, vérifiés propres (aucune marque, aucun site homonyme) mais la piste a été abandonnée en cours de route sans avoir été formellement invalidée, Jean-Marc étant parti explorer un concurrent adjacent (`easyfichiers.com`) puis, de fil en aiguille, l'API de Pappers. Vérification de l'API Pappers menée à la demande de Jean-Marc : modèle freemium (100 crédits gratuits à l'inscription puis facturation au crédit, abonnements à partir de 20€/mois) — mais surtout, ses CGU interdisent explicitement toute extraction/réutilisation de sa base de données et, clause spécifique, toute utilisation "pour alimenter, enrichir ou nourrir un service, produit, système ou solution tiers" : exactement l'usage qu'envisageait Jean-Marc pour les numéros de téléphone qu'il y avait repérés (donnée absente des sources SIRENE/INPI/BODACC officielles, donc nécessairement un enrichissement propriétaire de Pappers) — piste abandonnée sur ce constat, sans ambiguïté. **Nom finalement retenu : `entreprizh.bzh`** (jeu de mots entreprise/Breizh), trouvé par Jean-Marc, disponible et déjà accordé par l'association gestionnaire du `.bzh` — contrairement à `entreprises.bzh` en son temps. Vérifié par Claude Code (aucune marque, aucun site homonyme, le plus proche étant `entreprendre.bzh` et `mon-entreprise.bzh`, tous deux trop différents pour prêter à confusion) puis confirmé directement par Jean-Marc lui-même sur data.inpi.fr : aucun résultat. Achat décidé le soir même. **Statut.** Extraction Sirene : chaîne principale sur le 13 (Marseille, dernier département), file de reprise (74/75/76/77/88/2A/2B/48) prête à démarrer automatiquement à sa suite, code Corse corrigé et non encore testé en conditions réelles — premier point à vérifier à la prochaine reprise de session. Nom de domaine d'`entreprises.bzh` définitivement tranché (`entreprizh.bzh`), achat en cours par Jean-Marc. Logo toujours en réflexion, retouche manuelle envisagée mais pas commencée. Restructuration ENTREPRISES (siège/filiale, partitionnement, statut "P") toujours en attente de la fin complète de l'extraction, Jean-Marc envisageant d'ouvrir une session neuve à ce moment-là plutôt que de poursuivre celle-ci. `` avance : correctif du bug Corse dans `src/scripts/sirene_extract.py` (hors dépôt applicatif ASPIC comme les autres scripts d'extraction) ; `` avance de 31 à 32 — nouvelle version **V1.23.32**. ## 33. Extraction Sirene France entière terminée — 15 972 915 entreprises (19-20 septembre 2026) **Fin complète de l'extraction, sans incident sur la dernière ligne droite.** La chaîne principale a bouclé le 13 (Marseille) dans la nuit du 18 au 19 septembre, puis la file de reprise a enchaîné automatiquement et sans supervision sur les huit départements restants : 74 (terminé dans la nuit), 75/Paris (le plus gros morceau, ~15h de traitement à lui seul vu son volume), 76, 77, 88, puis **2A et 2B — premier vrai test du correctif Corse de la section 32, réussi du premier coup** (55 190 et 54 823 entreprises, aucune anomalie), et enfin 48 pour clore la liste. Le recalcul des statistiques par commune (`ent_communes_stats.py`) a suivi automatiquement en bout de chaîne (34 916 communes mises à jour). **Total national final : les 101 départements de France (métropole + DOM-TOM) sont extraits, pour 15 972 915 entreprises** — sensiblement au-dessus des projections successives de la conversation (8,5M initialement, recalibré à 13,4M section 29, puis à ~15-15,5M au fil de la reprise des derniers départements), l'écart provenant essentiellement des trois départements les plus lourds (Paris, Seine-Maritime, Seine-et-Marne) qui étaient restés très sous-captés depuis l'incident du 17 septembre jusqu'à leur réextraction complète. Disque à 60% d'occupation (115 Go/193 Go) une fois tout terminé, aucun processus d'extraction encore actif. **Statut.** Extraction Sirene : **terminée, définitivement**. Plus aucun script en tâche de fond. Le chantier de restructuration `ENTREPRISES` (siège/filiale, partitionnement natif MySQL évoqué section 29, split de `Phase4`, capture du statut "P") peut désormais démarrer sur des données complètes — Jean-Marc prévoit d'ouvrir une session neuve pour ce chantier plutôt que de poursuivre celle-ci. Nom de domaine `entreprizh.bzh` (section 32) en cours d'achat. Rétention des binlogs MySQL toujours réduite à 3 jours (section 31) — à remettre à 30 jours maintenant que la période d'écriture intensive est terminée, point non encore traité. `` n'avance pas dans cette section (fin d'un traitement déjà en cours, aucune modification) ; `` avance de 32 à 33 — nouvelle version **V1.23.33**.