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 parturbopackIgnoresans corriger la cause) ; - trois notions de « kernel » coexistaient : le type YAML
AtlasKernel(mort),composeKernelPrompt(vivant), le « Layer 2 : @Atlas kernel » delayer-system.ts(vivant).memory-layer.mdappelait 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, danshandler-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 danssrc/services/algorithms/prompts/, attribue au pilierintelligenceparownership.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
| Option | Pourquoi non |
|---|---|
Livrer @Atlas/kernel.yaml et le reste du dossier | Ce 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 getFallbackPrompt | Un 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 intelligence | Six 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.