Preuve · rapport

lecture-apteva-live-2026-09-13.md

Rapport de vérification de l'audit, texte brut · sur GitHub (dépôt privé, accès requis)

392 lignes · ← retour à l'audit · catalogue des preuves

1# Lecture en direct de l'instance Apteva de FLEXYLEAD — 13 septembre 2026
2
3**Version 2, après contre-audit.** Les corrections de `analyse/contre-lecture-apteva-2026-09-13.md` sont intégrées ; §12 en donne la liste et le sort de chacune.
4
5**Agent :** agent principal de session · **Régime :** lecture seule, GET uniquement, clé `read_only` remise par Marco
6**Clé employée :** `sk-63d18b48…` (« Greg Read Only »), conservée en `600` hors de `analyse/`, jamais recopiée
7**Fenêtre des appels :** 2026-09-13 09:45:43Z → 10:26:29Z · ~35 appels · toutes les réponses servies par `91.99.117.197`
8**Pièces :** réponses brutes conservées dans le scratchpad de la session. Ce qui n'y figure pas n'est pas une pièce.
9
10---
11
12## 0. Ce que la clé permet réellement — vérifié sur le code du jour
13
14**FAIT** — Dépôt public `apteva/server`, commit `b1d72aa` du **13/09 à 10 h 11** (`code/apteva-server-2026-09-13/`). La liste blanche des clés `read_only` est `api_key_access.go:57-86`. Elle **ne contient aucun chemin `/apps/`** ; le test du dépôt place `/apps/test/mcp` et `/apps/test/run` parmi les chemins refusés avec un 403 attendu (`api_key_access_test.go:32`). `/telemetry/*` **n'est pas un joker** : huit chemins sont énumérés (`:60-62`).
15
16**FAIT** — Dans tout le serveur, une clé `read_only` n'est traitée différemment qu'à **trois endroits**, tous sur la configuration d'un agent : `instances.go:2027`, `:2080`, `:2494`, via `readOnlyAgentConfig` (13 champs scalaires, `api_key_access.go:94-98`). Vérifié exhaustivement par le contradicteur : `isReadOnlyAPIKey(r)` n'existe qu'à `instances.go:2494` et `api_key_access.go:108`. **Aucune expurgation sur la télémétrie ni sur les fils.**
17
18**FAIT** — Les résultats d'outils sont conservés en télémétrie, tronqués à **1 000 octets** (`telemetry.go:619`), troncature appliquée à l'écriture (`:579`), pas à la lecture. **Démonstration directe** : le résultat de `admin_centres_list` du 19/08 fait 2 759 octets d'origine, conservés à 1 003, et sa lecture nous a donné la liste des centres partenaires en clair (§5.2).
19
20**FAIT** — Un appel refusé écrit `last_used` comme un appel accepté (`store.go:2641` avant le 403 de `auth.go:271`). **Aucun contre-test hors liste n'a donc été émis** : il coûterait une trace sans rien apprendre.
21
22**Conséquence centrale** : la clé n'ouvre pas les tables du CRM par la porte des applications, mais elle donne accès aux **directives complètes**, aux **MCP attachés par fil**, à la **télémétrie** et aux **1 000 premiers octets de chaque résultat d'outil**. Le périmètre utile dépasse largement ce qu'estimaient les notes du 09/09 et du 11/09.
23
24## 1. Version installée — la question ouverte depuis le 11/09 est close
25
26**FAIT** — `GET /api/version`, **non authentifiée** (`main.go:660-662`, sans `authMiddleware`), donc gratuite et sans trace de clé. Relevée à 09:45 puis à 09:59, identique :
27
28| Composant | Version |
29|---|---|
30| `apteva` · `core` · `cli` | **0.51.3** |
31| `dashboard` | 0.37.2 |
32| `integrations` | 0.39.1 |
33| `build` | **2026-09-13T08:14:18Z** |
34
35L'installation est **postérieure à la 0.51.0** : le mode `read_only` existe bien sur ce serveur, ce qui corrobore le champ `access` lu en base. Le binaire a été construit **ce matin à 08 h 14 UTC**.
36
37**Ce que cette version ne dit pas** : la version des **applications** (`tables`, `functions`, `telephony`…), qui suivent un registre distinct et publient plusieurs versions par jour. **Non lisible avec cette clé** — aucun manifeste d'outil collecté ne porte de version d'application, et aucun ne contient d'outil `tables`. C'est la question décisive laissée ouverte par `audit-donnees` (§11, point 9).
38
39## 2. Le compte et les clés
40
41**FAIT** — `GET /api/auth/me` : `user_id` **1**, `flexylead.gestion@gmail.com`, `role` **admin**, `mfa_enabled` **false**, créé le 13/05/2026, `interface_level: developer`, neuf capacités toutes actives.
42
43**FAIT** — `GET /api/auth/keys`, deux relevés (09:45:44 et 10:26:29) : **quatre clés, aucune expiration**, toutes sur le compte n°1.
44
45| id | nom | préfixe | accès | `last_used` à 09:45 | à 10:26 |
46|---|---|---|---|---|---|
47| 36834 | Greg Read Only | `sk-63d18b48` | **read_only** | 09:45:44 (nous) | 10:26:29 (nous) |
48| 36833 | GreG | `sk-a4b0ab68` | **read_only** | 10/09 13:44:56 | inchangé |
49| 25587 | Key 2 | `sk-c7b5f40a` | **read_write** | 28/08 09:38:10 | inchangé |
50| 1 | fleet | `sk-918fa4d9` | **read_write** | **09:45:40** | **09:53:56** |
51
52**FAIT** — La clé `fleet` a servi à 09:45:40 puis à 09:53:56, donc **de part et d'autre du démarrage de 09:47:39**. Le relevé est trop tardif pour attribuer ce démarrage — `last_used` n'est pas un historique, il est écrasé. **Attribution impossible**, et c'est un constat, pas une lacune de méthode : il n'existe pas de journal d'usage des clés.
53
54**HYPOTHÈSE inchangée** : « Key 2 », inactive depuis le 28/08, est une clé oubliée à faire révoquer.
55**FAIT** — Limite de débit : 60 appels par minute et par clé.
56
57## 3. Où tourne cette instance
58
59**FAIT** — `GET /api/settings/server` renvoie `geoip.database_path` = `/var/lib/apteva-fleet/flexylead-vultr/geoip/GeoIP2-Country.mmdb`. Le dossier de données de l'instance de parc s'appelle **`flexylead-vultr`**.
60
61**HYPOTHÈSE** (rétrogradée sur objection du contradicteur) — Ce chemin n'expose qu'un répertoire de données. Il indique un **nom** choisi pour la bascule Vultr ; il ne prouve pas où le processus s'exécute.
62
63**FAIT** — Toutes les réponses ont été servies par **`91.99.117.197`**, adresse **Hetzner** (`clients.your-server.de`). `public_url.effective` = `https://agents.flexylead.com`, source `db`.
64
65**FAIT** — Relevé DNS du 13/09 (serveurs autoritaires Google, TTL 14400) : `agents`, `dashboard`, `commerciaux`, `qualite`, `partenaires`, `commerciaux.test` → tous sur `91.99.117.197`. `app.` et `crm.` **n'ont jamais existé** : ils ne figurent pas à l'inventaire des noms créés (`migration-technique-2026-09-03.md:40-52`) — leur absence n'est pas un symptôme. Un certificat Let's Encrypt a été délivré le **11/09 à 05 h 43 UTC** pour `commerciaux.test.flexylead.com`, donc un défi ACME a été honoré depuis cette machine ce matin-là.
66
67**FAIT, et l'objection du contradicteur est levée par une source neuve** — Le sondage de `95.179.222.52` (ICMP 2/2, port 22 ouvert, 80 et 443 filtrés) a été émis par l'agent principal ce matin, et l'adresse était alors non attribuée. **Elle l'est désormais : `GET /v2/instances` du compte Vultr donne `main_ip = 95.179.222.52` pour `flexylead-vultr-vx1-paris`.** La machine est celle de FLEXYLEAD ; l'hypothèse d'une machine étrangère est éliminée. Détail dans `analyse/lecture-vultr-live-2026-09-13.md`.
68
69**SUGGÉRÉ** — La production est **servie depuis Hetzner** et la machine Vultr **reçoit des données sans encore servir** : DNS intégralement sur Hetzner, API Apteva répondant depuis Hetzner, ports 80/443 filtrés côté Vultr, et 288 Go entrants sur Vultr ce matin. La réserve reste que DNS et exécution peuvent diverger — le dossier en a un précédent (`releve-activite-scaleway-2026-09-07.md:8-16`).
70
71## 4. Treize agents, deux projets — et un démarrage à 09:47:40
72
73**FAIT** — `GET /api/projects` : **Flexylead** (`1778674225986-34533e84d347a861`, créé le 13/05) et **Staging** (`1783685516365-52b95c5d1996ca31`, créé le 10/07).
74
75**FAIT** — `GET /api/instances`, deux relevés à neuf minutes d'intervalle :
76
77| id | nom | projet | 09:45 | 09:54 | PID | démarré | `core_version` |
78|---|---|---|---|---|---|---|---|
79| 1 | Assistant Flexylead | PROD | stopped | stopped | 0 | — | **(vide)** |
80| 3 | Dépanneur | PROD | stopped | **running** | 960807 | 09:47:39 | 0.51.3 |
81| 4 | Standardiste Test | staging | running | running | 945441 | 08:20:21 | 0.51.3 |
82| 5 | Standardiste | PROD | stopped | **running** | 960816 | 09:47:39 | 0.51.3 |
83| 166 | Dépanneur | staging | running | running | 945497 | 08:20:32 | 0.51.3 |
84| 167 | Vigie | PROD | stopped | **running** | 960837 | 09:47:40 | 0.51.3 |
85| 168 | Vigie | staging | running | running | 945532 | 08:20:42 | 0.51.3 |
86| 169 | Administration | staging | running | running | 945555 | 08:20:47 | 0.51.3 |
87| 170 | Administration | PROD | stopped | **running** | 960846 | 09:47:40 | 0.51.3 |
88| 171-174 | Assistants (commercial, superviseur, gérant, administration) | staging | stopped | stopped | 0 | — | **0.50.2** |
89
90**FAIT** — Les quatre agents 171-174, créés le 08/09, sont restés en **`core_version` 0.50.2** avec une **cible 0.51.3** : ils n'ont jamais pris la mise à jour, et sont arrêtés depuis. L'agent 1 n'a **aucune** `core_version`.
91
92**FAIT** — `uptime_seconds` passe de 249 à 427 entre 09:51:49 et 09:54:47 pour les agents 3, 167 et 170 : **+178 s pour 178 s d'horloge**, ce sont de vrais processus.
93
94### 4.1 Le démarrage de 09:47 : ce n'est pas nous, et ce n'est pas un redémarrage du serveur
95
96**FAIT** — Notre appel `/telemetry/project-tools` est horodaté **09:47:00**, soit **39 secondes** avant le premier démarrage. La coïncidence est plus serrée que ce que la version 1 écrivait (« deux minutes »).
97
98**SUGGÉRÉ — la phase 1 n'a pas été violée.** Le contradicteur a fait la vérification que la version 1 escamotait : sur les huit sites d'appel de `startManagedAgent`, **le seul joignable par un GET est `GET /platform/helper`** (`main.go:1230` → `platform_agent.go:934`), qui **n'est pas dans la liste blanche** et n'a pas été appelé. `startAgentOnDemand` sort immédiatement si `idle_shutdown_after` est vide (`access_policy.go:411`). Réserve assumée : un `omitempty` empêche d'exclure absolument un démarrage à la demande.
99
100**FAIT — le serveur n'a pas redémarré.** Deux preuves : l'échelonnement des quatre démarrages est de **0,33 s** (`.569 / .898 / 40.233 / .572`), incompatible avec `boot_resume_delay: 5s` ; et avec `update_policy: restart` et `reattachEnabled=false` (`instances.go:2215`), les agents de staging auraient changé de PID — or 4, 166, 168 et 169 conservent **PID et port**. L'**HYPOTHÈSE « redémarrage du superviseur de parc » est retirée.** En revanche la série 08:20:21→08:20:52 correspond bien à ce mécanisme, et suit le build de 08:14:18.
101
102**FAIT — correction d'un fait erroné de la version 1.** La séquence de réveil complète (`thread.spawn` ×2, `event.received` ×2, `memory.recall`, `tool.catalog`, `tool.manifest`, `llm.start`, `pace`) s'est produite **deux fois**, non trois : le 13/09 à 08:20:52 et à 09:47:40. Le 12/09 à 23:28:51 n'a ni `thread.spawn`, ni `event.received`, ni `tool.catalog`, et porte `iteration: 4`. **Une seule occurrence précède donc notre session.**
103
104**FAIT** — `GET /api/version` donne le même `build` à 09:45 et 09:59 : **le démarrage de 09:47 n'est pas un déploiement.**
105**FAIT** — L'agent 167 avait un `next_wake_at` au 11:03:15 : il a démarré **avant** son réveil programmé. Le déclencheur n'est pas son minuteur.
106
107**HYPOTHÈSE, la seule qui subsiste** : une action authentifiée en écriture — tableau de bord ou clé `read_write`, dont `fleet` — a démarré ces quatre agents. **Non attribuable** (§2). Le faisceau extérieur la renforce : une bascule de données était en cours ce matin même (`lecture-vultr-live-2026-09-13.md` §4).
108
109### 4.2 Ce que `status` vaut — correction d'une conclusion trop large
110
111**FAIT** — `status` n'est **pas** un instantané périmé : `enrichAgentRuntime` l'écrase par `IsRunning` à chaque lecture (`instances.go:1581-1590`). C'est une **mesure vivante et exacte, mais ponctuelle**. La version 1 écrivait « toute conclusion du dossier fondée sur *l'agent est arrêté* doit être reprise » : **retiré**, aucune conclusion du dossier n'en dépend, et le piège était déjà consigné le matin même (`lecture-vultr-2026-09-13-cadrage-apteva.md:260`).
112
113**FAIT — piège de lecture confirmé** : sur l'agent 1, réellement arrêté, `/status` renvoie `iteration: 0`, `uptime_seconds: 0`, `memories: 0`, `rate: "stopped"`. Ce sont des constantes de branche (`instances.go:3302-3315`), pas une mesure.
114
115## 5. Ce à quoi les agents touchent
116
117**FAIT** — `GET /instances/{id}/threads` n'applique aucune expurgation. **Réserve de lecture essentielle** : pour un agent **arrêté**, cette réponse vient du `config.json` sur disque — c'est une **configuration persistée, pas un attachement vivant**.
118
119| agent | projet | fil | MCP déclarés | outils |
120|---|---|---|---|---|
121| **1** Assistant Flexylead | **PROD** | `chat-quality` | **`tables-db`, `storage`** | — |
122| 3 Dépanneur | PROD | main | `agent-output`, `channels`, `tickets` | 0 |
123| 3 | PROD | 2 fils `chat-conv` | **`code`** | 7 (sans `spawn`/`kill`) |
124| 3 | PROD | `depanneur-worker` | — | **21, dont 12 `tickets_*`** |
125| 5 Standardiste | PROD | main | `flexylead-bookings` | — |
126| 167 Vigie | PROD | main | `agent-output`, `channels`, `tasks` | — |
127| **170** Administration | **PROD** | main | `agent-output`, `channels`, **`functions`** | — |
128| **170** | **PROD** | `chat-conv-7f1f1…` | `channels`, **`flexylead-admin`** | 10 |
129| 170 | PROD | `chat-conv-99f92…` | `channels`, `functions` | — |
130| 168 Vigie | staging | main | + **`tasks`**, `functions` | — |
131| **169** Administration | staging | `chat-conv-f0630…` | `channels`, `functions`, **`flexylead-admin`** | 10 |
132
133**FAIT** — `llm.done` de l'agent 170 déclare `active_mcp_count: 17` et `always_mcp_count: 4` : **le nombre de MCP disponibles dépasse largement ce que liste un fil.**
134**FAIT** — Les fils de conversation portent `evolve` et `update` ; `spawn` et `kill` **ne sont pas universels** (absents des deux fils `chat-conv` de l'agent 3).
135
136### 5.1 Un agent de production est **configuré** pour atteindre les tables — jamais réalisé
137
138**FAIT** — L'agent **1**, projet Production, fil `chat-quality`, déclare les MCP `tables-db` et `storage`. Sa directive de fil dit — **citation rectifiée**, elle nomme l'app **`tables`**, pas `tables-db` :
139
140> « Tu as accès à la base de données via les outils MCP de l'app `tables` (lecture seule *recommandée*) […] **Utilise `tables_query` (SQL escape hatch) pour les filtres autres que la PK** — `rows_search where:{col}` est silencieusement no-op pour les colonnes non-id. Pour trouver la table SQL : `SELECT id FROM tables_meta WHERE name = ?`, puis `SELECT * FROM t_<id>`. »
141
142**FAIT — la capacité n'a jamais été exercée, et rien ne prouve qu'elle soit vivante :**
143- L'agent 1 totalise **0 événement sur 7 jours**, **0 appel d'outil** sur tout l'historique, et **aucun manifeste d'outil n'a jamais été émis** pour lui.
144- L'agent étant arrêté, la déclaration de MCP vient du disque : **configuration, pas attachement**.
145- Aucun outil `tables_*` n'apparaît dans les statistiques d'outils du projet Production.
146
147Le titre de la version 1 (« les tables sont bien atteintes par un agent ») est donc **corrigé en « est configuré pour atteindre »**.
148
149**Ce que `audit-donnees` a établi sur le fond** (livrable `donnees-filtre-inoperant-2026-09-13.md`, dépôt `apteva/apps` rafraîchi au commit `5a64116`) :
150- **La directive se trompe sur la cause.** Une colonne inconnue **lève une erreur** (`rows.go:1366`). Ce qui était silencieusement ignoré, c'est la **forme objet** de l'argument `where`, là où le contrat attend un **tableau** (`types.go:300-305`) — d'où un `SELECT` sans `WHERE`, borné à 50 lignes, avec un `total` pris sur la table entière.
151- **Le défaut a existé du 05/05 au 05/09/2026** et a été corrigé en v0.1.15 (`99f71685`) par un refus explicite. **Savoir s'il est actif aujourd'hui dépend de la version de `tables` installée — que cette clé ne permet pas de lire.**
152- **Le CRM n'est pas exposé** : sur 752 occurrences, **350 en forme tableau, 0 en forme objet**.
153- **La méthode enseignée par la directive est refusée depuis le 10/07** : `tables_meta` et le motif `t_[0-9]+` sont sur liste noire (v0.1.10).
154- **`tables_query` est en lecture seule**, garantie par trois mécanismes serveur indépendants. **Mais les 17 outils du MCP comprennent 9 outils d'écriture, aucun marqué `app_only`** : attacher ce MCP ouvre `rows_delete` et `tables_drop` sur les 31 tables, avec pour seul reste de garde un `confirm` que le modèle fournit lui-même.
155
156### 5.2 L'agent « Administration » : la capacité est réelle, l'usage est nul
157
158**FAIT** — Les agents **170 (production)** et **169 (staging)** déclarent le MCP `flexylead-admin` — **sur un fil `chat-conv`, réactif. Le fil autonome `main` ne le porte pas.** La nuance est décisive : ce MCP n'est pas dans les mains de la boucle autonome.
159
160**FAIT — aucune écriture n'a jamais été faite.** Balayage de **tous** les appels d'outils enregistrés :
161- Agent 170, fenêtre **19/08/2026 → 13/09 09:48**, 73 appels : `pace` ×60, `channels_send` ×7, `send` ×3, `search_tools` ×1, et **`admin_centres_list` ×2** — deux **lectures**, le 19/08.
162- Agent 169, 40 appels : `admin_centres_list` ×2 et `admin_routing_read` ×1, le 19/08 ; `functions_functions_list` ×6.
163- **`admin_economics_apply` : jamais appelé.** Aucun outil d'écriture, sur aucun des deux agents, sur toute la fenêtre.
164
165**FAIT** — Les deux lectures du 19/08 ont réussi (`success: true`) et leur résultat, tronqué de 2 759 à 1 003 octets, nous est revenu en clair : identifiants, noms et statut partenaire des centres.
166
167**FAIT** — Aucun des **11 manifestes d'outils** de l'agent 170 (du 08/09 au 13/09) ne contient d'outil `admin_*`. Les manifestes sont **par fil** : celui du fil qui déclare `flexylead-admin` (10/09 11:57:54) porte 10 outils, dont aucun outil admin. **SUGGÉRÉ : depuis au moins le 08/09, le MCP `flexylead-admin` est déclaré mais ne fournit plus d'outils au modèle.** Il en fournissait le 19/08, puisqu'il a servi.
168
169**FAIT — ce que `audit-argent` a établi sur le fond** (`argent-agent-administration-2026-09-13.md`) :
170- `admin_economics_apply` n'écrit pas lui-même : il enchaîne deux invocations de `flexylead-manage-production-economics`, dont les écritures portent sur **trois tables** — barème partenaire, **prime des commerciaux**, coûts de production.
171- **`confirm=true` est bien contrôlé côté serveur** (`flexylead-admin-mcp.mjs:531-533`) — la formule de la version 1 (« le garde-fou n'est pas dans le code ») est **fausse et retirée**. La formulation juste : ce contrôle ne vérifie qu'un booléen que l'agent fournit lui-même ; **un second appel du même agent n'est pas un accord humain.** Ni nonce, ni approbateur distinct, ni couplage avec une simulation, ni enregistrement de l'accord.
172- **Aucune trace d'auteur** : pas de `created_by` sur ces tables, alors que `stats_periods` en a deux. Une écriture par l'écran d'administration et une écriture par l'agent sont **indiscernables après coup**.
173- **Et le chemin est peut-être en panne** : `economicsApply` est le **seul** outil d'écriture du fichier à ne pas utiliser `forwardableActor(actor)` (`:546` contre dix autres), ce qui fait échouer la cible dès la lecture sur « Session gérant non authentifiée ». **Le barème n'est pas protégé par le garde-fou, il est peut-être protégé par un défaut** — et une seule ligne corrigée armerait tout le chemin.
174- **Une formule partielle ne complète pas la formule en vigueur : elle la remplace par les défauts.** Recalcul sur les indicateurs du 03/09 : 68 € en base contre **90 €** avec un `apply {base_amount: 85}`, soit **+22 €/contrat, +4 400 €/mois, 52 800 €/an par centre**. Échelle : **1 € de base = 2 400 €/an et par centre.**
175- **« L'historique n'est jamais recalculé » est vrai dans le code.** En revanche **le « 26 » n'existe nulle part** : les périodes sont des lignes de données, le seul repli du code est le mois civil.
176
177**FAIT** — Le bloc que la plateforme injecte elle-même dans les directives — « Server-managed behavior instructions (autonomous). **These are instructions, not enforced approval gates.** » — est présent dans **les treize** directives, et non dans les quatre assistants seulement comme l'écrivait la version 1. Le constat en est renforcé.
178
179### 5.3 Un MCP `code` resté attaché contre sa propre directive
180
181**FAIT** — L'agent 3 « Dépanneur » (production) porte le MCP `code` sur deux fils, alors que sa directive dit : « Tu n'utilises plus l'application Code : ni ses dépôts, ni ses tickets, ni la lecture de source. » **L'interdiction est textuelle, l'accès est resté.** Son fil `depanneur-worker` porte 21 outils dont 12 `tickets_*` en écriture (`create`, `update`, `set_status`, `comment`, `link`).
182
183### 5.4 Le standardiste téléphonique, Twilio, et un webhook sans signature
184
185**FAIT** — L'agent 5 (production) est le plus actif : **9 045 événements, 1 034 appels de modèle, 15,8 M de jetons en entrée, 208 fils ouverts et refermés, 41 erreurs** sur 7 jours au 13/09 09:50. Séquence du 12/09 13:29 : `realtime.session_started` (`gemini-3.1-flash-live-preview`, `google-realtime`), `bridge_connected` (pcm16, 24 kHz), `proxy.closed` avec `close_reason: "Twilio call…"`.
186
187**FAIT — ce que `audit-integrations` a établi** (`integrations-twilio-fournisseurs-2026-09-13.md`) :
188- **Twilio n'est pas un pair de Ringover et Telnyx : c'est un transporteur interchangeable de l'app `telephony`** (`compatible_slugs: [twilio, telnyx, plivo, signalwire, vonage]`). La déclaration de Marco du 23/07 sur l'abstraction transporteur **passe à `FAIT`** — la première du dossier à être vérifiée.
189- **Coexistence, pas remplacement** : `provider IN ('ringover','twilio')`. Topologie : appelant → Ringover → renvoi vers un numéro Twilio → sidecar `telephony` → fil temps réel → `google-realtime`.
190- **Le CRM code `provider = "twilio"` en dur** en huit endroits. Changer de transporteur côté plateforme — une ligne de configuration — **arrêterait silencieusement l'ingestion des appels IA dans le CRM**.
191- **Piège de migration jamais porté au tableau** : l'app **réécrit le webhook du numéro chez Twilio**, avec des URL dérivées du `public_url` de la plateforme, c'est-à-dire `agents.flexylead.com` — qui pointe encore sur Hetzner. Le changement de domaine se règle **numéro par numéro via un outil MCP**.
192- **Constat distinct et lourd** : il y a **deux** webhooks Ringover. Celui de `smart-routing` est vérifié sérieusement (HMAC). **`ringover-call-events`, qui écrit les appels et donc les compteurs facturés, n'a aucune vérification de signature** — ni secret, ni horodatage, sur 4 000 lignes.
193- **La résolution de l'appelant a un défaut silencieux** : si l'appariement échoue, le prospect créé porte **le numéro de pont** comme téléphone, avec `source: "twilio_ai"`.
194- **Double comptage possible** : la garde est une fenêtre de 10 secondes sur les fins de numéros ; si la jambe Ringover arrive en retard — ce que le dossier documente — le même appel est compté deux fois. `SUGGÉRÉ`, **à porter à `audit-argent`**.
195
196### 5.5 La Vigie ne surveille rien, et c'est elle qui devrait alerter
197
198**FAIT** — Directive de l'agent 167 (production) : « Vous surveillez la santé de la plateforme […] » puis « **Votre configuration est en cours. Aucun contrôle périodique n'est encore défini. N'entreprenez aucune surveillance…** » Périmètre « strictement lecture et observation ».
199**FAIT** — 61 événements, 7 appels de modèle, 0 outil d'écriture, 0 fil engendré sur 7 jours.
200**Conséquence relevée par `audit-integrations` : la supervision est circulaire.** Le seul organe de surveillance est l'agent en panne, à qui sa propre directive interdit de surveiller.
201
202**FAIT** — Historique complet des appels d'outils de l'agent 167, du 18/08 au 13/09 11:03 : **27 appels, tous `pace`.** L'agent de surveillance de la production n'a jamais rien fait d'autre que se rendormir.
203
204### 5.6 Ce que les agents ont réellement écrit en production — balayage exhaustif
205
206**FAIT** — Historique **complet** des appels d'outils, agent par agent, relevé le 13/09 entre 14:15 et 14:25 UTC (`type=tool.call`, jusqu'à 1 000 événements) :
207
208| agent | projet | appels | écritures métier constatées | fenêtre |
209|---|---|---:|---|---|
210| **5** Standardiste | **PROD** | 1 000 (borne atteinte) | **43 `flexylead-bookings_create_booking`** | 19/08 → 13/09 |
211| 3 Dépanneur | PROD | 257 | **aucune** — 0 appel `tickets_*` | 14/08 → 13/09 |
212| 167 Vigie | PROD | 27 | aucune (que du `pace`) | 18/08 → 13/09 |
213| 170 Administration | PROD | 73 | aucune — 2 lectures `admin_centres_list` | 19/08 → 13/09 |
214| 1 Assistant | PROD | **0** | aucune | — |
215| 169 Administration | staging | 40 | aucune — 1 `admin_routing_read`, 6 `functions_list` | — |
216| 166 Dépanneur | staging | 35 | aucune — 2 `tickets_tickets_list` | 17/08 → 13/09 |
217| 168 Vigie | staging | **0** | aucune | — |
218
219**FAIT — la seule écriture métier réelle d'une IA en production, ce sont 43 réservations.** Créées par le standardiste entre le **09/09 à 07:56** et le **12/09 à 13:29**, chacune avec un `provider_call_id` en `CA…` — la forme d'un identifiant d'appel **Twilio** —, un `ai_agent_id: "standardiste"` et un `request_id`. Rien depuis le 12/09 13:29. **Plancher et non mesure** : la réponse est bornée à 1 000 événements et le paramètre `since` ne la prolonge pas vers le passé.
220
221**FAIT — aucun outil de gestion de fonctions n'a jamais été appelé.** Ni `functions_create`, ni `functions_update`, ni `functions_deploy`, ni `functions_delete`, ni `functions_rollback`, ni `functions_invoke`, sur aucun des huit agents et sur toute la fenêtre lisible. Seul `functions_functions_list` a servi, six fois, en staging.
222
223### 5.7 La capacité réellement exercée, c'est la modification de soi-même
224
225**FAIT — le MCP `functions` expose treize outils aux agents de production**, relevés dans les manifestes des agents 168, 169 et 170 : `functions_list`, `get`, `versions`, `invocations`, `logs`, `capacity`, `prepare`, **`create`**, **`update`**, **`deploy`**, **`delete`**, **`rollback`**, **`invoke`**. Autrement dit, de quoi **créer, réécrire, déployer, revenir en arrière et supprimer les programmes du CRM**. Ces outils figurent dans **les onze manifestes** de l'agent 170, du 08/09 au 13/09 : contrairement aux outils `admin_*`, **ils sont bien matérialisés pour le modèle**.
226
227**FAIT** — Et la capacité que les agents exercent vraiment, c'est `update` sur leur propre configuration. L'agent 3 (production) l'a fait **13 fois**, plus 2 `spawn` :
228
229| date | action |
230|---|---|
231| 26/08 10:21 | s'attribue une liste d'outils sur son fil de conversation, dont `evolve`, `kill`, `spawn` |
232| 28/08 23:37 | réécrit sa propre directive |
233| 29/08 08:23:03 | **s'attribue les outils `code_issues_create`, `code_issues_update`, `code_repos_*`** — seul appel réussi des trois de ce jour ; **l'attribution ne subsiste pas** : ses deux fils ne portent plus que 7 outils, aucun `code_issues_*` |
234| 29/08 08:23 | **engendre deux fils** avec des directives qui prescrivent `code_issues_search` |
235| 01/09 07:57 | réécrit trois fois directives et outils de ses fils |
236| **13/09 08:20:31** | émet deux `update` avec `directive: ""` — **sans effet** : « *already has that configuration; no update or realtime reconnect was needed* » |
237| **13/09 09:47:54** | **réécrit la liste d'outils du fil `depanneur-worker`** — « *thread depanneur-worker updated* ». État constaté aujourd'hui : **21 outils, dont 12 `tickets_*`, dont 9 en écriture** |
238
239**Correction après contre-audit, sur pièces (`tres3.json`)** : les arguments des appels **sont** conservés en télémétrie (`type(args)=dict`, contenu complet). Mais **il faut lire les résultats, et je ne l'avais pas fait** : sur les 13 `update`, **9 ont réussi et 4 ont échoué** — `update requires id` le 29/08 à 08:17:36 et 08:23:43 (donc **l'attribution des outils du Code à ces deux instants n'a pas pris effet** ; seul l'appel de 08:23:03, qui porte un `id`, a réussi), `section_append requires section and content` le 27/08, et le 01/09 à 07:57:38 **un garde-fou de plateforme** : « *full directive replacement is disabled for structured Markdown directives; use section_append… do not pass the complete directive* ». **La plateforme refuse donc le remplacement intégral d'une directive structurée** — fait à porter au crédit de la conception.
240
241**Le constat qui en découle, niveau FAIT** : un agent autonome de production **s'accorde lui-même ses outils**. L'écart relevé au §5.3 — un MCP `code` resté attaché contre la lettre de la directive — n'est donc pas un oubli de configuration : **c'est l'agent qui s'était attribué ces outils le 29/08.** Et la liste d'outils d'un fil n'est pas un paramètre stable posé par un administrateur : c'est un état que l'agent modifie, la dernière fois **ce matin à 09:47:54**.
242
243**SUGGÉRÉ** — Aucun des sept autres agents n'a appelé `update`, `evolve`, `spawn` ni `kill` sur la fenêtre lisible. Le comportement est, à ce jour, propre à l'agent 3.
244
245### 5.8 L'outil de gestion des fonctions est cassé
246
247**FAIT** — Les six appels `functions_functions_list` de l'agent 169 (19/08, entre 09:00:13 et 09:00:24) ont **tous échoué** : `success: false`, résultat de 42 octets, **`error: parse: unexpected end of JSON input`**. Six tentatives en onze secondes, toutes en échec.
248
249**Conséquence pour l'audit** : le MCP `functions` est la seule voie de lecture qui aurait pu dire **quelles fonctions du CRM sont réellement déployées et en quelle version** — la question qui commande le constat 11 du document publié (la grille en mode malus) et, plus largement, toute la réserve « rien ne prouve que le code lu soit le code déployé ». **Cette voie est fermée deux fois** : elle n'est pas dans la liste blanche de la clé, et l'outil lui-même ne fonctionne pas.
250
251**SUGGÉRÉ** — Un MCP qui expose `create`, `update`, `deploy`, `delete` et `rollback` sur les programmes de production, et dont l'opération de **lecture** la plus simple échoue à l'analyse syntaxique, n'a probablement jamais servi. C'est une garantie de fait, pas une garantie de conception.
252
253### 5.9 Cinq dépôts de code vivent dans le projet de production
254
255**FAIT** — Résultat de `code_repos_list` de l'agent 3, le 27/08 à 23:37:22 — **1 917 octets d'origine, tronqués à 1 003** (`result_truncated: true` ; *correction : la version 2 écrivait « non tronqué », c'était faux*) : **5 dépôts** annoncés, tous sous `project_id: 1778674225986-34533e84d347a861`, c'est-à-dire **le projet Production**. Parmi eux `flexylead-legacy-app-redirect` (« Redirects retired legacy Flexylead web applications to the unified Partners app », créé le 11/08) et `flexylead-partenaires-unified`, avec des racines de stockage `/repos/by-id/{n}/`.
256
257**FAIT** — `list_connected` du 26/08 : « 3 servers: agent-output, channels, **code** ». L'agent 3 a bien eu le MCP `code` connecté et fonctionnel, et il s'était attribué ses outils d'écriture d'incidents la veille (§5.7).
258
259**Démonstration supplémentaire du §0** : ces deux résultats, comme la liste des centres et les 25 805 octets de campagnes de `admin_routing_read`, nous sont revenus **en clair par la télémétrie**, avec une clé en lecture seule qui n'a aucun accès aux applications.
260
261## 6. Les fournisseurs de modèles sont en panne sur le projet Staging
262
263**FAIT** — Agent **168** (Vigie staging), deux erreurs sur la même itération, le 13/09 à 08:20:42 :
264> `llm.provider_error` — **`Anthropic API error 401: {"type":"authentication_error","message":"API key is invalid."}`**, modèle `claude-sonnet-4-6`
265> `llm.error` — **`Gemini API error 400: "Unknown name \"additionalProperties\" at 'tools[0].fun…"`**, modèle `gemini-2.5-pro`
266
267**FAIT — le 401 récidive sur cinq jours**, relevé par requête filtrée `type=llm.provider_error` : **08/09 18:50, 10/09 11:27, 11/09 07:00, 13/09 08:20** — huit événements au total, soit **un 400 Gemini puis un 401 Anthropic à ~160 ms d'intervalle** à chaque date. *Correction : la version 2 écrivait « deux occurrences chaque fois », en laissant croire à deux 401 ; c'est la paire primaire/repli, une fois par date.* Ce n'est pas un incident isolé.
268**FAIT** — Agent 168 : **0 appel de modèle abouti sur 7 jours**, et 60 événements `llm.error`, dont une boucle de reprise le 06/09 toutes les cinq minutes de 08:07 à 08:47.
269**FAIT — l'agent 4 a bien des erreurs**, contrairement à ce que concluait le contradicteur : **40 `llm.error` et 14 `llm.provider_error`**, dont un `Anthropic 401` le 08/09 à 19:58:33 et un `Gemini 400 "Multiturn chat is not enabled for models/antigravi…"`. Son objection venait d'une lecture non filtrée, bornée aux événements récents. **Le constat de la version 1 tient.**
270**FAIT** — Au même tour de boucle, 10 secondes après (08:20:52), l'agent 170 (production) réussit ses appels avec `claude-haiku-4-5-20251001` chez `anthropic`.
271**Le titre de la version 1, « une partie du parc », est borné à : le projet Staging.**
272
273### 6.1 Le fournisseur configuré n'est pas le fournisseur employé
274
275**FAIT** — `GET /instances/{id}/config` est dans la liste blanche et donne `default_provider`. Confronté au fournisseur réellement employé, relevé sur les événements `llm.done`, **il est faux pour deux agents sur huit** :
276
277| agent | projet | `default_provider` déclaré | fournisseur et modèle réellement employés | `cost_usd` | erreurs |
278|---|---|---|---|---|---|
279| 3 Dépanneur | PROD | anthropic | **anthropic** · `claude-haiku-4-5-20251001` | 6/6 | 2 |
280| 167 Vigie | PROD | anthropic | **anthropic** · `claude-haiku-4-5-20251001` | 6/6 | 0 |
281| 170 Administration | PROD | anthropic | **anthropic** · `claude-haiku-4-5-20251001` | 6/6 | 0 |
282| 5 Standardiste | PROD | google | **google** · `gemini-3.8-flash`, temps réel `gemini-3.1-flash-live-preview` | 0/12 | 41 |
283| 4 Standardiste Test | staging | google | **google** · `gemini-2.5-pro` | 0/3 | 54 |
284| 168 Vigie | staging | google | aucun appel abouti | — | 68 |
285| 166 Dépanneur | staging | **anthropic** | **google** · `gemini-2.5-pro`, `gemini-3.6-flash` | 0/12 | 0 |
286| 169 Administration | staging | **anthropic** | **google** · `gemini-3.8-flash`, `gemini-2.5-pro` | 0/6 | 6 |
287
288**Conséquence de méthode : `default_provider` n'est pas un indicateur fiable de ce qui tourne.** Toute lecture de la configuration doit être confrontée à `llm.done`. Le serveur, lui, annonce `effective_provider: anthropic` et `available_providers: [anthropic, google]` (`/settings/new-agent-provider`).
289
290**FAIT — la corrélation qui explique la panne est établie empiriquement** : l'agent 168 porte l'app `tasks` **et** tourne sur google → **zéro appel abouti**. L'agent 167 porte la même app `tasks` mais tourne sur anthropic → **zéro erreur**. Le défaut `additionalProperties` de `normalizeGeminiSchema` ne mord donc que du côté Google, exactement comme le code le prévoit.
291
292**FAIT** — Les agents 166 et 169, en Staging et sur google, **réussissent leurs appels**. L'hypothèse d'un identifiant Google invalide sur ce projet est donc **écartée**.
293
294**SUGGÉRÉ** — Le `401` Anthropic n'apparaît que comme **tentative de repli** des agents dont le primaire est google (4 et 168), alors que l'Anthropic employé en primaire par 3, 167 et 170 fonctionne. Deux entrées Anthropic coexistent donc probablement, dont celle empruntée par le chemin de repli est invalide. **Non vérifiable** : `/providers` n'est pas dans la liste blanche. **Question 3 pour Marco, reformulée en conséquence.**
295
296**FAIT — ce que `audit-integrations` a établi sur la cause :**
297- **Trois niveaux de configuration coexistent** : table `providers` chiffrée, portée **par projet avec repli global**, et surcharge par agent. Staging en 401 pendant que Production réussit est le comportement attendu de deux lignes distinctes, dont une cassée.
298- **Le 400 de Gemini est un défaut de la plateforme**, dans le binaire qui tourne : `normalizeGeminiSchema` (`core/provider_google.go:189-235`) recopie toutes les clés verbatim et ne retire jamais `additionalProperties`. Le motif vient des applications — `apps/mcp/tasks/tools.go:12-13` en met sur **tous** les outils `tasks_*`, et `flexylead-admin-mcp.mjs` sur ses 20 schémas.
299- **La production est concernée en puissance** : les agents 167, 169 et 170 portent les mêmes applications. **Ils ne tombent pas uniquement parce que leur clé Anthropic fonctionne.**
300- **Le repli fait un seul saut, et il est épuisé d'emblée** : `Fallback` renvoie une alternative unique, et `permanentProviderError` classe **400 comme 401**, donc **zéro reprise** pour les deux erreurs observées.
301- **Risque de bascule** : les adaptateurs temps réel **réutilisent la clé du fournisseur texte**. La clé Google des appels Gemini est celle dont dépend la session du standardiste — 85,5 % de la dépense modèle du parc.
302
303## 7. Coût et volume sur 7 jours
304
305**FAIT** — `GET /telemetry/stats?instance_id=N&period=7d`, **relevés horodatés** — voir la réserve de méthode ci-dessous.
306
307| id | agent | projet | événements | appels modèle | jetons entrée | coût $ | erreurs |
308|---|---|---|---:|---:|---:|---:|---:|
309| 1 | Assistant Flexylead | PROD | 0 | 0 | 0 | 0,00 | 0 |
310| 3 | Dépanneur | PROD | 488 | 44 | 1 019 250 | 1,10 | 2 |
311| 5 | Standardiste | PROD | 9 045 | 1 034 | 15 800 089 | **12,52** | 41 |
312| 167 | Vigie | PROD | 61 | 7 | 178 160 | 0,18 | 0 |
313| 170 | Administration | PROD | 208 | 19 | 716 832 | 0,83 | 0 |
314| 4 | Standardiste Test | staging | 247 | 7 | 52 039 | 0,02 | 32 |
315| 166 | Dépanneur | staging | 113 | 10 | 188 538 | 0,00 | 0 |
316| 168 | Vigie | staging | 143 | 0 | 0 | 0,00 | 32 |
317| 169 | Administration | staging | 147 | 7 | 143 709 | 0,00 | 6 |
318
319*Agents de production relevés à 09:50 UTC ; agents de staging à 10:24 UTC.*
320
321**FAIT** — Total des agents de production : **14,63 $ sur 7 jours**, dont **85,5 %** pour le seul standardiste téléphonique.
322
323**RÉSERVE DE MÉTHODE, établie par l'expérience — la fenêtre de 7 jours glisse.** Les mêmes agents relevés à 09:50 puis à 10:24 donnent des chiffres différents : agent 4, 262 événements et **37** erreurs puis 247 et **32** ; agent 168, 158 et **37** puis 143 et **32**. Les deux relevés sont exacts à leur instant. **Tout chiffre issu de ce point de lecture doit être horodaté**, et la version 1 ne l'était pas.
324
325**FAIT — le coût est un plancher, et l'objection du contradicteur est vérifiée sur pièces.** Relevé sur les événements `llm.done` de cinq agents : `cost_usd` est **présent pour 100 % des appels Anthropic** (agents 3, 167, 170 : 6/6 chacun) et **absent pour 100 % des appels Google** (agents 4, 5, 166, 169 : 0/33). **Toute la dépense Gemini du parc est comptée à zéro.** C'est ce qui explique l'agent 166, à 10 appels aboutis, 0 erreur et coût nul : il tourne sur google.
326
327**FAIT** — Les 12,52 $ de l'agent 5 ne viennent donc **pas** de ses appels texte, mais de ses sessions temps réel : les événements `realtime.usage` portent un champ **`cost`** (distinct de `cost_usd`), avec le détail des jetons et des secondes audio en entrée et en sortie, sur `gemini-3.1-flash-live-preview`. **Les 85,5 % de la dépense mesurée sont de l'audio temps réel, pas du texte.**
328
329**Conséquence : le total de 14,63 $ n'est pas une mesure de la dépense modèle**, c'est la somme de l'audio temps réel et des seuls appels Anthropic. La dépense Gemini texte de tout le parc — y compris les 15,8 M de jetons en entrée de l'agent 5 et les appels quotidiens de 166 et 169 — **n'est comptée nulle part**. À porter à `audit-argent`.
330
331**FAIT** — `llm_calls` et `tokens_in` agrègent `realtime.usage` et les **jetons audio** : ils ne sont pas comparables à des appels texte.
332**RETIRÉ** — Le constat d'« accumulation de fils non clos » (27/0, 20/0, 10/0) ne tient pas : les deux mêmes fils de l'agent 170 sont re-engendrés à chaque démarrage, et l'agent ne porte que 3 fils.
333
334## 8. Réglages de serveur relevés
335
336**FAIT** — `access_policy` : inscription **verrouillée**, 3 inscriptions/IP/heure, **toutes les limites à 0**, donc sans plafond — projets, agents, agents en marche, appels de modèle quotidiens, jetons, appels simultanés. Neuf capacités actives.
337**FAIT** — `agent_lifecycle` : `boot_resume: staggered`, délai 5 s, `rollout_delay: 15 s`, `update_policy: restart`, `legacy_detach_active: false`.
338**FAIT** — `push_relay` activé vers `https://push.apteva.ai`, valeur par défaut non surchargée. **Portée établie par `audit-integrations` : abonnements et badges de notification mobile, pas les données d'appel.**
339**FAIT** — `geoip` actif, base DB-IP présente (8,3 Mo), mise à jour au **01/09**, `managed: true`, sans clé de licence. **Réserve** : sur un hôte à sortie filtrée, la base se figera en continuant d'annoncer `managed: true`.
340**FAIT** — `managed_llm_usage` du jour : 0 appel, 0 jeton. Les modèles passent par des clés propres, pas par la facturation gérée d'Apteva.
341**FAIT** — **ngrok : recherche négative** dans les deux arbres de code. La requalification du 03/09 est confirmée.
342
343## 9. Ce que cette lecture ne peut pas établir
344
345- **La version des applications installées** (`tables`, `functions`, `telephony`…) — dont dépend la question de savoir si le filtre silencieux du §5.1 est encore actif.
346- **Le contenu des tables**, les fonctions, les jobs, le stockage : `/apps/*` refusé.
347- **Qui a démarré les quatre agents à 09:47:39** — `last_used` n'est pas un historique.
348- **Qui a écrit quoi** : le journal d'actions d'agent n'est pas une route HTTP.
349- **Les identifiants et cibles des MCP** : `mcp_servers` est expurgé. On connaît les **noms** déclarés par fil.
350- **À qui appartient le compte Twilio** : `/connections` refusé.
351- **La source réellement déployée** de `flexylead-project-telephony-event`, dont dépend un constat de divergence comportementale signalé par `audit-integrations`.
352
353## 10. Ce qui a changé de statut grâce à cette lecture
354
355| Constat antérieur | Nouveau statut |
356|---|---|
357| « La version installée est inconnue » (11/09) | **Close** : 0.51.3, build du 13/09 08:14:18Z, par un point de lecture non authentifié |
358| « L'abstraction transporteur est une déclaration non vérifiée » (03/09) | **FAIT** — première déclaration de Marco vérifiée par le code |
359| « `95.179.222.52` non attribuée » (09/09) | **Attribuée** — machine FLEXYLEAD, par l'API Vultr |
360| « La lecture seule n'existe pas au niveau de la clé » (10/09) | **Faux depuis 0.51.0**, déjà corrigé le 11/09, confirmé aujourd'hui en base |
361| « ngrok, question ouverte » (03/09) | **Close** — négatif dans les deux arbres |
362| « Pas de journal d'actions Vultr » (cadrage du matin, point fragile) | **Vérifié** : `/v2/account/activity` → 404 |
363
364## 11. À demander à Marco
365
3661. **Un compte distinct** (`user` + `viewer`) et une clé émise depuis lui ; révocation des deux clés `read_only` du compte n°1 et de « Key 2 » (`read_write`, inactive depuis le 28/08).
3672. **Qui a démarré les quatre agents de production le 13/09 à 09:47:39**, et par quel moyen.
3683. **La clé Anthropic invalide** du projet Staging, en 401 les 08, 10, 11 et 13/09.
3694. **Le `additionalProperties` des schémas d'outils** refusé par Gemini, qui annule toute reprise.
3705. **Pourquoi un agent de production est configuré avec un accès base** et une directive qui enseigne une échappatoire SQL — méthode d'ailleurs refusée par le code depuis le 10/07.
3716. **Le MCP `tables` sans marqueur `app_only`** : 9 outils d'écriture, dont `rows_delete` et `tables_drop`, exposés dès l'attachement.
3727. **`flexylead-admin` sur un agent** : ce qui empêche `admin_economics_apply` d'aboutir sans accord humain, sachant que `confirm=true` ne vérifie qu'un booléen fourni par l'agent, et qu'aucune colonne d'auteur n'existe.
3738. **Pourquoi `economicsApply` seul n'utilise pas `forwardableActor`** — est-ce un défaut, et depuis quand ?
3749. **La version installée de `tables`** : ≥ 0.1.15 ou non. Un seul nombre décide si le filtre silencieux est éteint ou actif.
37510. **Le MCP `code` resté attaché** à l'agent 3 contre sa directive.
37611. **`ringover-call-events` sans vérification de signature**, alors que l'autre webhook Ringover en a une.
37712. **Les agents 171-174 restés en `core` 0.50.2** avec une cible 0.51.3.
378
379## 12. Sort des objections du contre-audit
380
381**Acceptées et intégrées :** l'argument sur le démarrage réécrit (§4.1) ; retrait de l'hypothèse du redémarrage de serveur ; « deux fois, non trois » ; 39 s et non 2 min ; `status` mesure vivante mais ponctuelle (§4.2) ; retrait de « toute conclusion doit être reprise » ; citation `tables` et non `tables-db` ; « configuré pour atteindre » (§5.1) ; `flexylead-admin` sur fil réactif et non autonome ; retrait de « le garde-fou n'est pas dans le code » ; bloc « not enforced » dans les 13 directives ; bornage du §6 au projet Staging ; 85,5 % ; absence de modèle Google dans la tarification ; retrait de l'accumulation de fils ; `core` 0.50.2 des agents 171-174 ; 12 `tickets_*` sur 21 ; `spawn`/`kill` non universels ; `push_relay` borné ; `main.go:660-662` ; `auth.go:271` ; §3 rétrogradé en HYPOTHÈSE.
382
383**Rejetées après vérification :**
384- **« L'agent 4 n'a pas d'erreurs »** — il en a 54, dont un `Anthropic 401`. L'objection venait d'une lecture non filtrée (§6).
385- **« Retirer le sondage de `95.179.222.52` »** — l'objection portait sur une adresse non attribuée. L'API Vultr l'attribue à FLEXYLEAD (§3). Le sondage est maintenu et sa provenance explicitée.
386
387**Réserve du contradicteur reprise à notre compte :** les statistiques de staging manquaient aux pièces ; elles ont été relevées à nouveau et sauvegardées, ce qui a révélé le glissement de la fenêtre de 7 jours (§7).
388
389---
390
391*Ce document décrit l'instance servie par `agents.flexylead.com` le 13/09/2026 entre 09:45 et 10:26 UTC, pendant qu'une bascule de données était en cours vers Vultr. Deux relevés à neuf minutes d'intervalle ont divergé sur cinq agents ; deux relevés de statistiques à trente-quatre minutes d'intervalle ont divergé sur tous les compteurs.*
392