ADRADR-0022 · Le kernel @Atlas est un texte versionne, pas un dossier YAML a charger

ADR-0022 — Le kernel @Atlas est un texte versionne, pas un dossier YAML a charger

src/features/ai/prompts/loader.ts etait un chargeur de 240 lignes pour un dossier @Atlas/ : kernel.yaml (identite, lois), routing.yaml (routage par mots-cles vers un specialiste), un dossier agents/, un dossier skills/…

Statut

Accepté · 2026-09-17

Piliers : ai-platform, intelligence

Contexte

src/features/ai/prompts/loader.ts etait un chargeur de 240 lignes pour un dossier @Atlas/ : kernel.yaml (identite, lois), routing.yaml (routage par mots-cles vers un specialiste), un dossier agents/, un dossier skills/, une couche utilisateur. Avec son composeur (composer.ts), son routeur (router.ts), sa famille de types (types/index.ts, 277 lignes : AtlasKernel, AtlasAgent, AtlasRouting, AtlasUserConfig, AtlasInstance…) et le barrel orchestrator/index.ts qui les re-exportait, un peu plus de 900 lignes. Aucun de ces fichiers n'existe plus : cette decision les supprime.

Le dossier n'a jamais existe. ai-platform/0116 l'a verifie sur quatre fronts : absent de l'arbre, absent de .gitignore, aucun kernel.yaml nulle part, jamais cree par le build, et git log --all -- '@Atlas' vide. Six appelants (le chat web via handler-prompt-kernel.ts, WhatsApp via bot-handlers.ts et whatsapp-per-store.ts, la voix via /api/evi/chat/completions, plus les deux barrels) gardaient tous sur isAtlasAvailable(), qui repondait false a chaque tour depuis le premier jour. Le bloc etait saute, un « prompt de repli » prenait la main. C'est lui que chaque utilisateur a toujours eu.

Ce que ca coutait n'etait pas nul :

  • le chemin du dossier etait construit au runtime depuis process.cwd(), donc le bundler tracait le projet entier dans chaque fonction qui atteignait ce module : 5 688 fichiers traces pour une mediane de 456 (platform-ops/0102, corrige par turbopackIgnore sans corriger la cause) ;
  • trois notions de « kernel » coexistaient : le type YAML AtlasKernel (mort), composeKernelPrompt (vivant), le « Layer 2 : @Atlas kernel » de layer-system.ts (vivant). memory-layer.md appelait le sien « iRen kernel », du nom que l'orchestrateur portait avant 2026 (ai-platform/0603) ;
  • le composeur mort portait sa propre injection PCM (« Layer 4b »), a cote de la vraie, loadPCMBlock, dans handler-system-layers.ts, et un test de 174 lignes prouvait le comportement d'un code que rien n'appelait ;
  • le composeur 3 couches vivant, composeAtlasPrompt, vivait dans src/services/algorithms/prompts/, attribue au pilier intelligence par ownership.json : modifier une des six regles de base que chaque tour lit etait une PR cross-pilier (ai-platform/0599).

Un chargeur qui attend depuis toujours n'est pas un bug a corriger vite, c'est une intention a confirmer. 0116 etait blocked sur cette question depuis le 29 aout.

Décision

Le kernel @Atlas est un seul texte versionne, src/features/ai/prompts/kernel.ts (getKernelPrompt). Le chat web le compose avec le contexte du tour (composeKernelPrompt), puis le splice en Layer 2 avec composeAtlasPrompt (prompts/layer-system.ts, rapatrie dans le pilier). WhatsApp lui ajoute son contexte de canal, la voix a son propre kernel court dans sa route. Le chargeur YAML, son composeur, son routeur, sa famille de types et le barrel qui les re-exportait sont supprimes ; les six gardes disparaissent avec eux.

Le routage par mots-cles n'est pas remplace, parce qu'il n'a jamais tourne. La poche memoire d'un tour est forceAgent, puis atlas.agent de la requete, puis atlas ; la delegation reelle a un specialiste est celle de l'equipe (orchestrator/team/delegate-tool.ts).

Alternatives écartées

OptionPourquoi non
Livrer @Atlas/kernel.yaml et le reste du dossierCe serait une seconde source de verite pour l'identite et les lois, a cote du texte TypeScript qui tourne deja. Rien dans le produit n'edite ce dossier (aucun ecran, aucun outil d'admin) : un format de fichier n'achete rien qu'un module TS n'a pas, et il ramene le chargement au runtime depuis cwd que 0102 a mesure. La personnalisation par le marchand existe deja et vit en base (Store.systemPrompt, Store.instructions, Layer 3), pas dans un YAML du depot
Garder le chargeur « au cas ou »C'est l'etat qui a coute cet ADR : 900 lignes que personne ne lit, trois mots pour une chose, et un test qui prouve du code mort. knip ne le voyait pas parce que le barrel rendait tout atteignable
Garder le nom getFallbackPromptUn nom qui dit « repli » pour le seul chemin apprend a chaque lecteur a chercher le chemin principal, qui n'existe pas. C'est exactement comme ca que 0116 a ete ouvert : depuis un avertissement de build, jamais depuis un besoin produit
Laisser layer-system.ts cote intelligenceSix regles de base du prompt et le composeur qui les splice sont la surface de prompt du pilier ai-platform. Les trois blocs qu'il compose (loi marketplace-first, contexte plateforme, overlay boutique) restent cote intelligence, la ou ils sont enregistres

Conséquences

Ce que ca supprime. prompts/{loader,composer,composer.test,router,index}.ts, types/index.ts, orchestrator/index.ts. Les types Atlas* du chargeur n'ont plus d'existence ; ComposeOptions.pcm non plus, la seule injection PCM est loadPCMBlock. Le champ atlas.enabled de la requete ne change que le niveau de contexte, ce qui etait deja vrai (le repli tournait quel que soit ce drapeau).

Ce que ca rend visible. L'overlay d'activite recente (buildRecentActivityOverlay) echouait dans un catch {} muet ; il journalise chat.prompt.activity_overlay_failed.

La dette acceptee. Le kernel est un long litteral TypeScript en francais, edite comme du code. C'est voulu : un deploy le propage a tous les tenants, comme le pack de setup (features/ai/setup-pack/) et les skills natifs. Le jour ou un marchand doit editer l'identite ou les lois, la reponse est un overlay en base, pas un dossier YAML.

Le signal qui indiquerait de revisiter. Un besoin de kernel different par tenant (marque blanche) : alors une colonne, pas un fichier.

Comment c'est appliqué

src/test/one-atlas-kernel.test.ts : les fichiers supprimes ne reviennent pas, aucun fichier de src/ n'importe un chargeur d'@Atlas/, ni ne garde sur une disponibilite du kernel ; les trois canaux (chat web, WhatsApp, voix) partent de prompts/kernel.ts ou de leur kernel de canal ; le composeur 3 couches vit dans le pilier. src/test/prompt-laws-have-tools.test.ts continue de prouver que la loi marketplace-first est splicee dans ce composeur.