SPB Git forge

spb/groupe-ka

Public

Groupe KA — site du holding + KA ID (compte unique & SSO des 7 plateformes). Next.js 16, SQLite, Google & Apple login.

81commits 1branches 0releases
89.2 MBsize
maindefault branch
22 days agolast push
TypeScript 70.4% HTML 18.4% JavaScript 4% Python 3.8% CSS 3.4%

Agents gardiens: page /agents ultra-détaillée + section accueil refondée (ka2/ka4/ka6 nouveau rôle: réparation autonome des connecteurs) + nav/footer + bannière /bots

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed 1 mo ago (Aug 23, 2026) parent a66f044

4 changed files +649 −40

added src/app/agents/page.tsx +566 −0
@@ -0,0 +1,566 @@
1 +// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
2 +import type { Metadata } from "next";
3 +import type { ReactNode } from "react";
4 +
5 +export const metadata: Metadata = {
6 + title: "Les agents gardiens — ka·2, ka·4, ka·6",
7 + description:
8 + "ka·2, ka·4 et ka·6 sont les agents gardiens autonomes du Groupe KA : ils détectent les connecteurs en panne, les réparent avec Claude directement dans le code des plateformes, prouvent la réparation par un test réel, et reviennent en arrière si ça empire. Fonctionnement complet, garde-fous et transparence.",
9 +};
10 +
11 +/* ------------------------------------------------------------------ */
12 +/* Données */
13 +/* ------------------------------------------------------------------ */
14 +
15 +type Guardian = {
16 + digit: string;
17 + accent: string; // couleur thème de l'agent (bleu / orange / mauve)
18 + soft: string; // teinte pâle
19 + domain: string;
20 + url: string;
21 + tagline: string;
22 + node: string;
23 + perimetre: { app: string; url: string }[];
24 + extra?: string;
25 +};
26 +
27 +const GUARDIANS: Guardian[] = [
28 + {
29 + digit: "2",
30 + accent: "#5b9df5",
31 + soft: "#e3effc",
32 + domain: "www.ka2.bot",
33 + url: "https://www.ka2.bot",
34 + tagline: "Gardien immobilier & local",
35 + node: "veille depuis M4M36 · intervient sur M3U96b et M4M64a",
36 + perimetre: [
37 + { app: "Lou·Ka", url: "https://www.lou-ka.com" },
38 + { app: "Immo·Ka", url: "https://www.immo-ka.com" },
39 + { app: "Resto·Ka", url: "https://www.resto-ka.com" },
40 + ],
41 + },
42 + {
43 + digit: "4",
44 + accent: "#ff9f2e",
45 + soft: "#ffefd9",
46 + domain: "www.ka4.bot",
47 + url: "https://www.ka4.bot",
48 + tagline: "Gardien mobilité & quotidien",
49 + node: "veille depuis M4M36 · intervient sur M4M64b et M3U96a",
50 + perimetre: [
51 + { app: "Auto·Ka", url: "https://www.auto-ka.com" },
52 + { app: "Food·Ka", url: "https://www.food-ka.com" },
53 + { app: "Sorti·Ka", url: "https://www.sorti-ka.com" },
54 + ],
55 + },
56 + {
57 + digit: "6",
58 + accent: "#a78bfa",
59 + soft: "#f0e8fc",
60 + domain: "www.ka6.bot",
61 + url: "https://www.ka6.bot",
62 + tagline: "Gardien flagship — gros volumes",
63 + node: "veille depuis M4M36 · intervient sur M4M64a et M3U96a/b",
64 + perimetre: [
65 + { app: "Fabri·Ka", url: "https://www.fabri-ka.com" },
66 + { app: "Job·Ka", url: "https://www.job-ka.com" },
67 + { app: "Créa·Ka", url: "https://www.crea-ka.com" },
68 + ],
69 + extra: "+ agent par défaut de toute nouvelle plateforme",
70 + },
71 +];
72 +
73 +const BOUCLE = [
74 + {
75 + num: "01",
76 + title: "Détecter",
77 + body: (
78 + <>
79 + La supervision centralisée du groupe (api-ka) classe en continu plus
80 + de 2 600 connecteurs selon quatre états mesurés : <b>ok</b>,{" "}
81 + <b>dégradé</b> (volume sous 50 % de la médiane historique),{" "}
82 + <b>cassé</b> (au moins trois synchronisations consécutives en échec ou
83 + à zéro résultat) et <b>endormi</b> (aucun succès depuis plus de deux
84 + fois la cadence attendue). Chaque gardien lit cette supervision toutes
85 + les cinq minutes ; un connecteur cassé ou endormi de son périmètre
86 + devient un <b>incident</b>, horodaté et public.
87 + </>
88 + ),
89 + },
90 + {
91 + num: "02",
92 + title: "Réparer",
93 + body: (
94 + <>
95 + Le gardien dépêche une session <b>Claude Code</b> (le modèle frontière
96 + Claude Fable 5 d&apos;Anthropic, en mode agent) <b>sur le nœud même qui
97 + héberge la plateforme, dans son dépôt de code</b>. La session reçoit un
98 + dossier complet : état de santé du connecteur, portrait de
99 + l&apos;app entière (pour distinguer une panne isolée d&apos;un problème
100 + systémique), historique des interventions précédentes, et une démarche
101 + imposée — lire la documentation du dépôt, lire les journaux,
102 + reproduire la panne, corriger de façon minimale, re-tester pour vrai,
103 + redémarrer uniquement le processus concerné, committer.
104 + </>
105 + ),
106 + },
107 + {
108 + num: "03",
109 + title: "Surveiller",
110 + body: (
111 + <>
112 + Une réparation déclarée n&apos;est pas une réparation confirmée.
113 + L&apos;incident passe en <b>surveillance pendant huit heures</b> :
114 + c&apos;est la supervision api-ka — un système indépendant de
115 + l&apos;agent — qui doit constater le retour du connecteur à
116 + l&apos;état ok, avec de vrais volumes de données. L&apos;agent ne se
117 + note pas lui-même.
118 + </>
119 + ),
120 + },
121 + {
122 + num: "04",
123 + title: "Reculer",
124 + body: (
125 + <>
126 + Si la plateforme tombe après l&apos;intervention, ou si le connecteur
127 + n&apos;a pas guéri au terme de la fenêtre de surveillance, le gardien
128 + <b> annule lui-même son travail</b> : retour git au commit d&apos;avant
129 + la mission, redémarrage des processus, et l&apos;échec est affiché
130 + publiquement. Trois tentatives au maximum par incident, espacées de
131 + six heures ; au-delà, l&apos;incident est marqué « abandonné —
132 + intervention humaine requise ».
133 + </>
134 + ),
135 + },
136 +];
137 +
138 +const DEMARCHE = [
139 + "S'imprégner du dépôt : CLAUDE.md, README et fiches docs/connecteurs (URL de la source, stratégie de lecture, pièges connus).",
140 + "Lire les journaux du processus de synchronisation et y retrouver les traces d'erreur du connecteur en panne.",
141 + "Reproduire la panne en exécutant réellement le connecteur — constater l'erreur, pas la deviner.",
142 + "Diagnostiquer la cause racine : structure HTML changée, API déplacée, blocage anti-robot, pagination cassée, certificat, site fermé…",
143 + "Corriger de façon minimale et ciblée, dans les conventions du dépôt — jamais de réécriture opportuniste.",
144 + "Re-tester pour vrai : le connecteur doit rapporter un volume plausible, comparé à sa médiane historique. Inventer ou câbler des données est interdit.",
145 + "Redémarrer uniquement le processus concerné, puis vérifier que le site de la plateforme répond.",
146 + "Committer avec un message signé [ka2|ka4|ka6], qui documente la cause et le correctif. Jamais de push automatique.",
147 +];
148 +
149 +const GARANTIES = [
150 + {
151 + title: "Test réel obligatoire",
152 + body: "Une réparation n'existe que si le connecteur re-livre de vraies données, en volume plausible. Un correctif « qui a l'air bon » sans test mesuré est compté comme un échec.",
153 + },
154 + {
155 + title: "Rollback automatique",
156 + body: "Chaque mission part d'un instantané git. Si la plateforme se dégrade ou si la supervision ne confirme pas la guérison, l'agent revient au commit d'avant — sans qu'on le lui demande.",
157 + },
158 + {
159 + title: "Jamais de push autonome",
160 + body: "Les commits des agents restent sur le nœud de la plateforme. Rien ne part vers le dépôt central sans une session humaine. L'humain garde le dernier mot sur l'histoire du code.",
161 + },
162 + {
163 + title: "Périmètre verrouillé",
164 + body: "Interdits absolus : toucher aux autres plateformes du nœud, à la configuration des processus, au schéma des bases, aux clés. Désactiver un connecteur pour « guérir » sa santé est explicitement proscrit.",
165 + },
166 + {
167 + title: "Sources mortes respectées",
168 + body: "Un site fermé, passé sous mot de passe ou définitivement disparu n'est pas forcé. L'agent documente, conclut « source morte », et n'insiste pas. Les échecs légitimes sont affichés comme tels.",
169 + },
170 + {
171 + title: "Transparence totale",
172 + body: "Chaque action — commande exécutée, fichier lu, diagnostic, commit, coût API en dollars — est diffusée en direct sur le site public de l'agent et archivée dans un registre consultable, mission par mission.",
173 + },
174 +];
175 +
176 +const EXEMPLES = [
177 + {
178 + source: "cabanedupicbois.com",
179 + app: "Fabri·Ka",
180 + diag: "Le serveur WordPress s'était mis à émettre un marqueur d'encodage (BOM UTF-8) avant sa réponse JSON — invisible à l'œil, fatal au décodeur. Correctif de quatre lignes : re-décodage tolérant avant l'escalade.",
181 + },
182 + {
183 + source: "virginmady.com",
184 + app: "Fabri·Ka",
185 + diag: "La boutique avait migré de WooCommerce vers Shopify sans préavis. L'agent a détecté la migration, retrouvé le nouveau point d'accès et rebranché le connecteur.",
186 + },
187 + {
188 + source: "domainevallierrobert.ca",
189 + app: "Fabri·Ka",
190 + diag: "Un plugin WordPress injectait 6 Ko de HTML avant la réponse JSON du catalogue. Diagnostic à l'octet près, correctif minimal, volumes revenus.",
191 + },
192 + {
193 + source: "foodcrayon.com",
194 + app: "Fabri·Ka",
195 + diag: "Boutique passée en mode « bientôt ouvert », protégée par mot de passe. L'agent a conclu à un échec légitime et n'a rien forcé — exactement ce qu'on attend de lui.",
196 + },
197 +];
198 +
199 +/* ------------------------------------------------------------------ */
200 +
201 +function Section({
202 + id,
203 + kicker,
204 + title,
205 + children,
206 +}: {
207 + id?: string;
208 + kicker: string;
209 + title: ReactNode;
210 + children: ReactNode;
211 +}) {
212 + return (
213 + <section id={id} className="mt-16 scroll-mt-24 sm:mt-20">
214 + <p className="kicker">{kicker}</p>
215 + <h2 className="gk-display mt-2 text-[22px] font-bold tracking-[-0.03em] uppercase sm:text-[26px]">
216 + {title}
217 + </h2>
218 + {children}
219 + </section>
220 + );
221 +}
222 +
223 +export default function AgentsPage() {
224 + return (
225 + <main className="mx-auto max-w-6xl px-4 pt-10 pb-4 sm:px-6 sm:pt-14">
226 + {/* ---------- Héros ---------- */}
227 + <header className="max-w-3xl">
228 + <p className="kicker">ka·2 · ka·4 · ka·6 — les gardiens, depuis août 2026</p>
229 + <h1 className="gk-display mt-3 text-[clamp(30px,5vw,52px)] leading-[1.04] font-bold tracking-[-0.03em]">
230 + Des agents qui réparent les connecteurs{" "}
231 + <span className="hl">pendant que vous dormez</span>
232 + </h1>
233 + <p className="mt-5 max-w-2xl text-[15px] leading-relaxed text-ink-2">
234 + Les plateformes ·Ka reposent sur des centaines de connecteurs qui
235 + lisent le web à la source. Le web bouge : un site migre, une API
236 + disparaît, un encodage change — et un connecteur casse. Depuis août
237 + 2026, ka·2, ka·4 et ka·6 ne sont plus des éclaireurs de découverte :
238 + ce sont des <b>agents gardiens autonomes</b>. Ils détectent la panne,
239 + ouvrent le code, la réparent, prouvent que ça marche — et si ça
240 + empire, ils reviennent en arrière. Sans intervention humaine, et
241 + entièrement en public.
242 + </p>
243 + <div className="mt-6 flex flex-wrap gap-2">
244 + {GUARDIANS.map((g) => (
245 + <a
246 + key={g.digit}
247 + href={g.url}
248 + target="_blank"
249 + rel="noopener noreferrer"
250 + className="stat-chip !text-[11.5px]"
251 + >
252 + <span
253 + aria-hidden="true"
254 + className="mr-1 inline-block h-[8px] w-[8px] rounded-full border border-ink align-middle"
255 + style={{ background: g.accent }}
256 + />
257 + {g.domain} — en direct ↗
258 + </a>
259 + ))}
260 + </div>
261 + </header>
262 +
263 + {/* ---------- Les trois gardiens ---------- */}
264 + <Section
265 + id="gardiens"
266 + kicker="La flotte · trois agents, dix plateformes"
267 + title={
268 + <>
269 + Trois gardiens, <span className="hl">chacun son territoire</span>
270 + </>
271 + }
272 + >
273 + <div className="mt-7 grid gap-5 lg:grid-cols-3">
274 + {GUARDIANS.map((g) => (
275 + <article key={g.digit} className="gk-card gk-card-hover p-5 sm:p-6">
276 + <div className="flex flex-wrap items-baseline justify-between gap-3">
277 + <span className="gk-mono text-[12px] font-bold text-green">
278 + GARDIEN
279 + </span>
280 + <span className="klabel">{g.domain}</span>
281 + </div>
282 + <h3 className="gk-display mt-4 inline-flex items-baseline gap-[5px] text-[32px] font-bold tracking-[-0.04em]">
283 + ka
284 + <span
285 + className="inline-block -rotate-2 rounded-md px-[8px] pb-[3px] text-paper"
286 + style={{ background: "#141814", color: g.accent }}
287 + >
288 + ·{g.digit}
289 + </span>
290 + </h3>
291 + <p className="gk-display mt-3 text-[15.5px] font-bold uppercase tracking-[-0.01em]">
292 + {g.tagline}
293 + </p>
294 + <p className="gk-mono mt-2 text-[11px] text-ink-3">{g.node}</p>
295 + <ul className="mt-5 space-y-2 border-t-[1.5px] border-dashed border-[rgba(20,24,20,0.25)] pt-5">
296 + {g.perimetre.map((p) => (
297 + <li key={p.app} className="flex items-center gap-3 text-[13.5px]">
298 + <span
299 + aria-hidden="true"
300 + className="h-[5px] w-[5px] flex-none rotate-45 border border-ink"
301 + style={{ background: g.accent }}
302 + />
303 + <a
304 + href={p.url}
305 + className="font-semibold underline-offset-4 hover:underline"
306 + >
307 + {p.app}
308 + </a>
309 + </li>
310 + ))}
311 + {g.extra ? (
312 + <li className="gk-mono pt-1 text-[11px] text-ink-3">{g.extra}</li>
313 + ) : null}
314 + </ul>
315 + <a
316 + href={g.url}
317 + target="_blank"
318 + rel="noopener noreferrer"
319 + className="btn btn-primary mt-6 w-full"
320 + >
321 + Le regarder travailler ↗
322 + </a>
323 + </article>
324 + ))}
325 + </div>
326 + </Section>
327 +
328 + {/* ---------- La boucle de garde ---------- */}
329 + <Section
330 + id="boucle"
331 + kicker="Le fonctionnement · détecter, réparer, surveiller, reculer"
332 + title={
333 + <>
334 + La boucle de garde, <span className="hl">en quatre temps</span>
335 + </>
336 + }
337 + >
338 + <div className="mt-7 grid gap-4 sm:grid-cols-2">
339 + {BOUCLE.map((b) => (
340 + <article key={b.num} className="gk-card gk-card-hover p-5 sm:p-6">
341 + <span className="gk-mono text-[12px] font-bold text-green">{b.num}</span>
342 + <h3 className="gk-display mt-3 text-[17px] font-bold uppercase">{b.title}</h3>
343 + <p className="mt-3 text-[13.5px] leading-relaxed text-ink-2">{b.body}</p>
344 + </article>
345 + ))}
346 + </div>
347 + </Section>
348 +
349 + {/* ---------- La démarche imposée ---------- */}
350 + <Section
351 + id="demarche"
352 + kicker="Sous le capot · le protocole d'une mission"
353 + title={
354 + <>
355 + Huit étapes, <span className="hl">imposées à chaque mission</span>
356 + </>
357 + }
358 + >
359 + <p className="mt-3 max-w-2xl text-[14.5px] text-ink-2">
360 + L&apos;agent n&apos;improvise pas : chaque mission de réparation suit
361 + un protocole strict, écrit dans son ordre de mission. Il travaille
362 + dans le dépôt de code réel de la plateforme, avec les mêmes outils
363 + qu&apos;un développeur — terminal, journaux, tests — et l&apos;ordre
364 + des opérations n&apos;est pas négociable.
365 + </p>
366 + <ol className="mt-7 grid gap-3 sm:grid-cols-2">
367 + {DEMARCHE.map((d, i) => (
368 + <li key={d} className="gk-card flex gap-4 p-4 sm:p-5">
369 + <span className="gk-mono text-[13px] font-bold text-green">
370 + {String(i + 1).padStart(2, "0")}
371 + </span>
372 + <span className="text-[13px] leading-relaxed text-ink-2">{d}</span>
373 + </li>
374 + ))}
375 + </ol>
376 + <div className="gk-card mt-6 !bg-ink p-6 text-paper sm:p-7">
377 + <p className="kicker !text-lime">S&apos;il faut escalader</p>
378 + <p className="mt-3 max-w-3xl text-[13.5px] leading-relaxed text-[rgba(245,243,238,0.75)]">
379 + Quand une source se met à bloquer les lecteurs automatiques,
380 + l&apos;agent dispose de la même pile d&apos;escalade que les
381 + connecteurs du groupe : requête directe, puis lecteur bas niveau,
382 + puis rendu de page complet (Scrapfly), déblocage spécialisé (Bright
383 + Data), proxys résidentiels canadiens (Oxylabs) et, en dernier
384 + recours, les acteurs d&apos;extraction maison (Apify). Pour
385 + retrouver une source déplacée, il cherche — Serper (recherche
386 + Google ciblée Québec) et Tavily. Il regarde d&apos;abord comment le
387 + dépôt utilise déjà ces services, et fait pareil.
388 + </p>
389 + </div>
390 + </Section>
391 +
392 + {/* ---------- Cas réels ---------- */}
393 + <Section
394 + id="cas"
395 + kicker="Pièces à conviction · premières missions, août 2026"
396 + title={
397 + <>
398 + Ce qu&apos;ils ont <span className="hl">vraiment réparé</span>
399 + </>
400 + }
401 + >
402 + <p className="mt-3 max-w-2xl text-[14.5px] text-ink-2">
403 + Dès sa première garde, ka·6 a traité la file d&apos;incidents de
404 + Fabri·Ka. Chaque mission ci-dessous est consultable sur son site —
405 + déroulé complet, diagnostic, commit et coût.
406 + </p>
407 + <div className="mt-7 grid gap-4 sm:grid-cols-2">
408 + {EXEMPLES.map((e) => (
409 + <article key={e.source} className="gk-card p-5">
410 + <div className="flex flex-wrap items-baseline justify-between gap-2">
411 + <span className="gk-mono text-[12.5px] font-bold">{e.source}</span>
412 + <span className="klabel">{e.app}</span>
413 + </div>
414 + <p className="mt-3 text-[13px] leading-relaxed text-ink-2">{e.diag}</p>
415 + </article>
416 + ))}
417 + </div>
418 + </Section>
419 +
420 + {/* ---------- Efforts commandés ---------- */}
421 + <Section
422 + id="efforts"
423 + kicker="Au-delà de la garde · le travail à la demande"
424 + title={
425 + <>
426 + On peut aussi <span className="hl">leur commander un effort</span>
427 + </>
428 + }
429 + >
430 + <p className="mt-3 max-w-2xl text-[14.5px] text-ink-2">
431 + Chaque site gardien comporte un poste de commande. Un opérateur muni
432 + du jeton peut y lancer une session entièrement autonome — elle
433 + travaille jusqu&apos;au bout, sans poser de question, et tout
434 + s&apos;affiche dans le flux public.
435 + </p>
436 + <div className="mt-7 grid gap-5 lg:grid-cols-2">
437 + <article className="gk-card gk-card-hover p-5 sm:p-7">
438 + <span className="gk-mono text-[12px] font-bold text-green">EFFORT 01</span>
439 + <h3 className="gk-display mt-3 text-[17px] font-bold uppercase">
440 + Nouveau connecteur
441 + </h3>
442 + <p className="mt-3 text-[13.5px] leading-relaxed text-ink-2">
443 + L&apos;agent cartographie ce que la plateforme couvre déjà, part
444 + en découverte (recherche ciblée Québec via Serper), évalue
445 + plusieurs sources candidates — volume, faisabilité, qualité,
446 + stabilité —, choisit la meilleure, puis construit le connecteur
447 + complet dans les conventions exactes du dépôt : lecture,
448 + extraction de tous les champs, déduplication, enregistrement,
449 + documentation, test en volume réel, commit.
450 + </p>
451 + </article>
452 + <article className="gk-card gk-card-hover p-5 sm:p-7">
453 + <span className="gk-mono text-[12px] font-bold text-green">EFFORT 02</span>
454 + <h3 className="gk-display mt-3 text-[17px] font-bold uppercase">
455 + Enrichissement d&apos;un connecteur
456 + </h3>
457 + <p className="mt-3 text-[13.5px] leading-relaxed text-ink-2">
458 + On choisit un connecteur existant dans la liste, et l&apos;agent
459 + en maximise la valeur : pagination complète pour couvrir tout le
460 + site source, champs manquants des fiches détail, robustesse aux
461 + changements de structure, détection des retraits — sans jamais
462 + casser le format de sortie dont dépendent les plateformes. Le
463 + résultat est mesuré avant/après.
464 + </p>
465 + </article>
466 + </div>
467 + </Section>
468 +
469 + {/* ---------- Garanties ---------- */}
470 + <Section
471 + id="garanties"
472 + kicker="Les garde-fous · l'autonomie sans les dérives"
473 + title={
474 + <>
475 + Autonomes, <span className="hl">pas incontrôlés</span>
476 + </>
477 + }
478 + >
479 + <div className="mt-7 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
480 + {GARANTIES.map((g) => (
481 + <article key={g.title} className="gk-card gk-card-hover p-5">
482 + <h3 className="gk-display text-[15px] font-bold uppercase">{g.title}</h3>
483 + <p className="mt-3 text-[13px] leading-relaxed text-ink-2">{g.body}</p>
484 + </article>
485 + ))}
486 + </div>
487 + </Section>
488 +
489 + {/* ---------- Architecture ---------- */}
490 + <Section
491 + id="architecture"
492 + kicker="L'architecture · pour les curieux"
493 + title={
494 + <>
495 + Comment c&apos;est <span className="hl">bâti</span>
496 + </>
497 + }
498 + >
499 + <div className="gk-card mt-7 overflow-x-auto">
500 + <table className="w-full min-w-[560px] text-left text-[13px]">
501 + <tbody>
502 + {[
503 + [
504 + "Le cerveau",
505 + "Trois orchestrateurs indépendants (un par gardien) sur un nœud dédié du parc MacLustr. Chacun tient son registre d'incidents et de missions, arbitre les priorités (cassé avant endormi, une mission à la fois) et sert son tableau de bord public en direct.",
506 + ],
507 + [
508 + "Les bras",
509 + "Un exécuteur léger sur chaque nœud qui héberge des plateformes. Il lance la session Claude Code dans le dépôt local, prend l'instantané git de sûreté, relaie chaque événement vers l'orchestrateur et sait annuler puis redémarrer proprement.",
510 + ],
511 + [
512 + "Le modèle",
513 + "Claude Fable 5 (Anthropic), en mode agent via Claude Code — le même outil qu'utilisent les développeurs du groupe, en session non interactive, plafonnée en tours et en durée.",
514 + ],
515 + [
516 + "Le juge",
517 + "La supervision api-ka, indépendante des agents : c'est elle qui déclare un connecteur cassé, et elle seule qui le déclare guéri. L'agent ne valide jamais son propre travail.",
518 + ],
519 + [
520 + "La mémoire",
521 + "Chaque mission garde son déroulé intégral : commandes, diagnostics, commit de base, commits produits, nombre de tours, durée, coût API en dollars. Le tout consultable publiquement, mission par mission.",
522 + ],
523 + ].map(([k, v]) => (
524 + <tr key={k} className="border-b border-[rgba(20,24,20,0.12)] last:border-0">
525 + <th className="gk-mono w-[130px] px-4 py-4 align-top text-[11px] font-bold tracking-[0.08em] text-ink-3 uppercase sm:px-5">
526 + {k}
527 + </th>
528 + <td className="px-4 py-4 leading-relaxed text-ink-2 sm:px-5">{v}</td>
529 + </tr>
530 + ))}
531 + </tbody>
532 + </table>
533 + </div>
534 + </Section>
535 +
536 + {/* ---------- CTA ---------- */}
537 + <section className="mt-16 sm:mt-20">
538 + <div className="gk-card overflow-hidden !bg-ink p-7 text-paper sm:p-10">
539 + <p className="kicker !text-lime">Zéro boîte noire, même pour les agents</p>
540 + <h2 className="gk-display mt-3 max-w-2xl text-[clamp(24px,4vw,40px)] leading-[1.02] font-bold tracking-[-0.03em] uppercase">
541 + Regardez-les <span className="text-lime">travailler</span>. En ce
542 + moment.
543 + </h2>
544 + <p className="mt-4 max-w-xl text-[14.5px] text-[rgba(245,243,238,0.75)]">
545 + Les trois tableaux de bord sont publics : incidents ouverts, flux
546 + d&apos;actions en temps réel, registre des missions, coûts. Ce que
547 + font nos agents n&apos;est pas un secret — c&apos;est un argument.
548 + </p>
549 + <div className="mt-7 flex flex-wrap gap-3">
550 + {GUARDIANS.map((g) => (
551 + <a
552 + key={g.digit}
553 + href={g.url}
554 + target="_blank"
555 + rel="noopener noreferrer"
556 + className="btn !border-lime !bg-transparent !text-lime hover:!bg-[rgba(217,242,107,0.12)]"
557 + >
558 + {g.domain} ↗
559 + </a>
560 + ))}
561 + </div>
562 + </div>
563 + </section>
564 + </main>
565 + );
566 +}
modified src/app/bots/page.tsx +16 −1
@@ -4,7 +4,7 @@ import type { Metadata } from "next";
4 4 export const metadata: Metadata = {
5 5 title: "Déclaration de transparence — Robots d'indexation",
6 6 description:
7 − "Fonctionnement des robots d'indexation du Groupe KA (ka·2, ka·4, ka·6) : données publiques uniquement, respect de robots.txt, charge minimale, retrait sur demande — zéro boîte noire.",
7 + "Principes de collecte du Groupe KA — données publiques uniquement, respect de robots.txt, charge minimale, retrait sur demande. Note : depuis août 2026, ka·2/ka·4/ka·6 sont des agents gardiens autonomes (voir /agents).",
8 8 };
9 9
10 10 const MAILTO = "gk-mono font-bold underline underline-offset-4 hover:text-ink";
@@ -252,6 +252,21 @@ function Bullet({ children }: { children: React.ReactNode }) {
252 252 export default function Bots() {
253 253 return (
254 254 <main className="mx-auto max-w-4xl px-4 pb-16 sm:px-6">
255 + <div className="gk-card mb-8 !bg-ink p-5 text-paper sm:p-6">
256 + <p className="kicker !text-lime">Mise à jour — août 2026</p>
257 + <p className="mt-2 max-w-3xl text-[13.5px] leading-relaxed text-[rgba(245,243,238,0.85)]">
258 + ka·2, ka·4 et ka·6 ne sont plus des robots d&apos;indexation : ce sont
259 + désormais les <b>agents gardiens autonomes</b> du groupe — ils
260 + détectent les connecteurs en panne, les réparent directement dans le
261 + code des plateformes et annulent leurs changements si ça empire.{" "}
262 + <a href="/agents" className="font-semibold text-lime underline underline-offset-4">
263 + Leur fonctionnement complet →
264 + </a>{" "}
265 + La présente déclaration continue de s&apos;appliquer à la collecte
266 + effectuée par les connecteurs des plateformes ·Ka.
267 + </p>
268 + </div>
269 +
255 270 <section className="pt-12 sm:pt-14">
256 271 <p className="kicker rise">Zéro boîte noire · nos robots</p>
257 272 <h1 className="gk-display rise mt-4 text-[clamp(30px,5vw,52px)] leading-[1] font-bold tracking-[-0.035em] uppercase [animation-delay:0.08s]">
modified src/app/layout.tsx +6 −2
@@ -118,7 +118,7 @@ const NAV_ITEMS = [
118 118 { href: "/#chiffres", label: "Chiffres" },
119 119 { href: "/#produits", label: "Plateformes" },
120 120 { href: "/#socle", label: "Socle" },
121 − { href: "/#bots", label: "Bots" },
121 + { href: "/agents", label: "Agents" },
122 122 { href: "/stats", label: "Stats" },
123 123 { href: "/rapports", label: "Rapports" },
124 124 { href: "/investisseurs", label: "Investisseurs" },
@@ -407,8 +407,12 @@ export default async function RootLayout({
407 407 Protection des renseignements personnels (Loi 25)
408 408 </a>{" "}
409 409 ·{" "}
410 + <a href="/agents" className="underline-offset-4 hover:text-lime hover:underline">
411 + Agents gardiens autonomes
412 + </a>{" "}
413 + ·{" "}
410 414 <a href="/bots" className="underline-offset-4 hover:text-lime hover:underline">
411 − Transparence des robots d&apos;indexation
415 + Transparence de la collecte
412 416 </a>{" "}
413 417 ·{" "}
414 418 <a href="/stats" className="underline-offset-4 hover:text-lime hover:underline">
modified src/app/page.tsx +61 −37
@@ -278,36 +278,53 @@ type Bot = {
278 278 const BOTS: Bot[] = [
279 279 {
280 280 digit: "2",
281 − accent: "#d9f26b",
281 + accent: "#5b9df5",
282 282 inkbox: "#141814",
283 283 domain: "www.ka2.bot",
284 284 url: "https://www.ka2.bot",
285 − tagline: "Le web québécois, cartographié entité par entité.",
285 + tagline: "Gardien immobilier & local.",
286 286 description:
287 − "Ka2 est un bot IA de cartographie : il parcourt le web québécois, identifie les entités — entreprises, organisations, personnes, sites web — et les documente. Propulsé par Claude Haiku 4.5 avec Firecrawl et Scrapfly, il ne copie pas les pages : il les comprend, puis les classe.",
288 − chips: ["4 types d'entités", "Propulsé par IA", "robots.txt respecté"],
287 + "ka·2 veille sur les connecteurs de Lou·Ka, Immo·Ka et Resto·Ka. Quand la supervision en déclare un cassé ou endormi, il dépêche une session Claude Code dans le dépôt de la plateforme, sur son nœud : diagnostic, correctif minimal, test en volume réel, commit signé — et rollback git automatique si ça empire.",
288 + chips: ["Lou·Ka · Immo·Ka · Resto·Ka", "Réparation autonome", "Flux public en direct"],
289 289 features: [
290 − "Découverte et classement : entreprises, organisations, personnes, sites web",
291 − "Chaque page lue est comprise par un modèle d'IA, pas seulement copiée",
292 − "Budget quotidien et délais entre requêtes — un crawl qui ménage les sites",
293 − "Données publiques seulement, Loi 25 et LPRPDE comme plancher",
290 + "Détection en continu via la supervision api-ka (scan toutes les 5 minutes)",
291 + "Répare dans le code réel de la plateforme, jamais à côté",
292 + "Surveillance de 8 h après chaque réparation avant de déclarer victoire",
293 + "Chaque diagnostic, commit et coût est affiché publiquement",
294 294 ],
295 295 },
296 296 {
297 297 digit: "4",
298 − accent: "#ff9f45",
298 + accent: "#ff9f2e",
299 299 inkbox: "#141814",
300 300 domain: "www.ka4.bot",
301 301 url: "https://www.ka4.bot",
302 − tagline: "Le deuxième éclaireur, avec l'activité à découvert.",
302 + tagline: "Gardien mobilité & quotidien.",
303 303 description:
304 − "Ka4 double la flotte de découverte : même moteur IA — Claude Haiku 4.5 avec Firecrawl et Scrapfly —, mais une classification élargie à cinq types d'entités et un tableau de bord où l'exploration se regarde en direct. Deux bots, deux fronts, une seule carte du web québécois.",
305 − chips: ["5 types d'entités", "Activité en direct", "robots.txt respecté"],
304 + "ka·4 garde Auto·Ka, Food·Ka et Sorti·Ka. Même boucle de garde : il reproduit la panne avant de la corriger, re-teste pour vrai contre la médiane historique du connecteur, redémarre uniquement le processus concerné — et revient au commit d'avant si la guérison n'est pas confirmée.",
305 + chips: ["Auto·Ka · Food·Ka · Sorti·Ka", "Test réel obligatoire", "Rollback automatique"],
306 306 features: [
307 − "Classification élargie : entreprises, organisations, personnes, sites web, données",
308 − "Tableau de bord public : l'activité du bot et ses découvertes, en direct",
309 − "Bascule automatique entre backends de lecture (Firecrawl → Scrapfly)",
310 − "Données publiques seulement, Loi 25 et LPRPDE comme plancher",
307 + "Distingue une panne isolée d'un problème systémique avant d'agir",
308 + "Pile d'escalade complète si la source bloque (rendu JS, proxys canadiens…)",
309 + "Trois tentatives maximum, puis remise à l'humain — jamais d'acharnement",
310 + "Une source morte est documentée, pas forcée",
311 + ],
312 + },
313 + {
314 + digit: "6",
315 + accent: "#a78bfa",
316 + inkbox: "#141814",
317 + domain: "www.ka6.bot",
318 + url: "https://www.ka6.bot",
319 + tagline: "Gardien flagship — les gros volumes.",
320 + description:
321 + "ka·6 tient le plus gros territoire : Fabri·Ka et ses ~1 700 connecteurs, Job·Ka, Créa·Ka — et toute nouvelle plateforme par défaut. Dès sa première garde, il a réparé des connecteurs que le web avait cassés : encodage corrompu, migrations de plateforme, API disparues.",
322 + chips: ["Fabri·Ka · Job·Ka · Créa·Ka", "~2 000 connecteurs sous garde", "Efforts commandés"],
323 + features: [
324 + "File d'incidents priorisée : les connecteurs cassés passent avant les endormis",
325 + "On peut lui commander un effort : nouveau connecteur ou enrichissement",
326 + "Sessions 100 % autonomes — il travaille jusqu'au bout sans rien demander",
327 + "Registre public des missions : déroulé, commits, durée, coût",
311 328 ],
312 329 },
313 330 ];
@@ -1082,28 +1099,30 @@ export default async function Home() {
1082 1099 </div>
1083 1100 </Section>
1084 1101
1085 − {/* ---------- Ka2 & Ka4 — les agents de découverte ---------- */}
1102 + {/* ---------- ka2 · ka4 · ka6 — les agents gardiens ---------- */}
1086 1103 <Section
1087 1104 id="bots"
1088 − kicker="Les éclaireurs du groupe · découverte web"
1105 + kicker="Les gardiens du groupe · maintenance autonome"
1089 1106 title={
1090 1107 <>
1091 − Avant d&apos;agréger, <span className="hl">les bots découvrent</span>
1108 + Quand un connecteur casse, <span className="hl">un agent le répare</span>
1092 1109 </>
1093 1110 }
1094 1111 >
1095 1112 <p className="mt-3 max-w-xl text-[14.5px] text-ink-2">
1096 − Les connecteurs ·Ka lisent des sources connues. Mais qui trouve les
1097 − sources ? Ka2 et Ka4, les agents de découverte web du groupe : des
1098 − bots IA qui explorent et cartographient le web québécois, entité par
1099 − entité, pour alimenter tout l&apos;écosystème.
1113 + Des centaines de connecteurs lisent le web à la source — et le web
1114 + bouge : sites qui migrent, API qui disparaissent, encodages qui
1115 + changent. Depuis août 2026, ka·2, ka·4 et ka·6 sont les agents
1116 + gardiens autonomes du groupe : ils détectent la panne, ouvrent le
1117 + code, la réparent, prouvent que ça marche — et reculent si ça
1118 + empire. <a href="/agents" className="font-semibold underline underline-offset-4 hover:text-green">Le fonctionnement complet, ultra-détaillé →</a>
1100 1119 </p>
1101 − <div className="mt-7 grid gap-5 lg:grid-cols-2">
1120 + <div className="mt-7 grid gap-5 lg:grid-cols-3">
1102 1121 {BOTS.map((b) => (
1103 1122 <article key={b.domain} className="gk-card gk-card-hover p-5 sm:p-7">
1104 1123 <div className="flex flex-wrap items-baseline justify-between gap-3">
1105 1124 <span className="gk-mono text-[12px] font-bold text-green">
1106 − BOT
1125 + GARDIEN
1107 1126 </span>
1108 1127 <span className="klabel">{b.domain}</span>
1109 1128 </div>
@@ -1153,28 +1172,30 @@ export default async function Home() {
1153 1172 </div>
1154 1173 <div className="gk-card mt-6 !bg-ink p-6 text-paper sm:p-7">
1155 1174 <p className="kicker !text-lime">
1156 − Le rôle des bots dans l&apos;écosystème
1175 + La boucle de garde, en quatre temps
1157 1176 </p>
1158 1177 <div className="mt-4 grid items-start gap-6 lg:grid-cols-2">
1159 1178 <p className="gk-display text-[clamp(24px,3.2vw,34px)] leading-[1.05] font-bold tracking-[-0.03em] uppercase">
1160 − Les bots découvrent
1179 + api-ka détecte
1161 1180 <br />
1162 − <span className="text-lime">→ ·Ka agrège</span>
1163 − <br />→ vous trouvez
1181 + <span className="text-lime">→ le gardien répare</span>
1182 + <br />→ ·Ka continue
1164 1183 </p>
1165 1184 <div>
1166 1185 <p className="max-w-md text-[13.5px] text-[rgba(245,243,238,0.75)]">
1167 − Ka2 et Ka4 sont les éclaireurs du groupe : ils cartographient
1168 − le terrain avant que les connecteurs ne s&apos;y branchent. Une
1169 − nouvelle boutique québécoise, un nouveau gestionnaire
1170 − immobilier, un concessionnaire qui ouvre — les bots les
1171 − repèrent, et les plateformes ·Ka les intègrent.
1186 + La supervision du groupe classe plus de 2 600 connecteurs en
1187 + continu. Un connecteur cassé devient un incident ; un incident
1188 + devient une mission Claude Code sur le nœud même de la
1189 + plateforme ; une réparation n&apos;est confirmée que par le
1190 + retour mesuré des données — et huit heures de surveillance.
1191 + Sinon : retour git au commit d&apos;avant, automatiquement.
1172 1192 </p>
1173 1193 <ul className="mt-5 space-y-2 border-t border-[rgba(245,243,238,0.15)] pt-5 text-[13px] text-[rgba(245,243,238,0.75)]">
1174 1194 {[
1175 − "Respectent systématiquement robots.txt",
1176 − "Ne traitent que des données publiques",
1177 − "Zéro boîte noire — leur fonctionnement est documenté sur ka2.bot et ka4.bot",
1195 + "Test réel obligatoire — un correctif sans données mesurées compte comme un échec",
1196 + "Rollback automatique si la plateforme se dégrade ou ne guérit pas",
1197 + "Jamais de push autonome — l'humain garde le dernier mot sur le code",
1198 + "Zéro boîte noire — flux d'actions, commits et coûts publics sur ka2.bot, ka4.bot et ka6.bot",
1178 1199 ].map((f) => (
1179 1200 <li key={f} className="flex gap-3">
1180 1201 <span
@@ -1185,6 +1206,9 @@ export default async function Home() {
1185 1206 </li>
1186 1207 ))}
1187 1208 </ul>
1209 + <a href="/agents" className="btn btn-lime mt-6 !border-lime">
1210 + Tout le fonctionnement en détail →
1211 + </a>
1188 1212 </div>
1189 1213 </div>
1190 1214 </div>
1191 1215