|
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'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'app entière (pour distinguer une panne isolée d'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'est pas une réparation confirmée. |
|
113 |
+ L'incident passe en <b>surveillance pendant huit heures</b> : |
|
114 |
+ c'est la supervision api-ka — un système indépendant de |
|
115 |
+ l'agent — qui doit constater le retour du connecteur à |
|
116 |
+ l'état ok, avec de vrais volumes de données. L'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'intervention, ou si le connecteur |
|
127 |
+ n'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'avant |
|
129 |
+ la mission, redémarrage des processus, et l'échec est affiché |
|
130 |
+ publiquement. Trois tentatives au maximum par incident, espacées de |
|
131 |
+ six heures ; au-delà, l'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'agent n'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'un développeur — terminal, journaux, tests — et l'ordre |
|
364 |
+ des opérations n'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'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'agent dispose de la même pile d'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'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'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'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'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'au bout, sans poser de question, et tout |
|
434 |
+ s'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'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'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'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'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'actions en temps réel, registre des missions, coûts. Ce que |
|
547 |
+ font nos agents n'est pas un secret — c'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 |
+} |