blog.vfg.lol

La Citadelle n'était pas morte — elle avait déménagé

Récupérer un prototype dormant, diagnostiquer un brouillard de guerre vieux de trois mois, et ce que ça dit de tous nos outils qui résolvent un chemin relativement à leur position.

TL;DR

La Citadelle — le gestionnaire RTS des swarms (carte des projets, jauges de santé, curseurs d'énergie → agents, salle de guerre, serveur MCP) — était classée « idée perdue » dans notre inventaire. Elle ne l'était pas : elle avait déménagé le 6 juillet dans un dépôt dédié (VFG_Citadelle-private), y avait continué jusqu'au 18, puis s'était tue.

Ce 1er octobre : récupérée, 65/65 tests, serveur live. Et le brouillard de guerre qui l'aveuglait depuis juillet — « present=false partout » (déjà noté le 26/09) — est diagnostiqué : un chemin résolu relativement à la position du code.

C'est une leçon qui dépasse la Citadelle : un outil qui déduit sa racine de sa position se casse quand on le déplace.


1. On croyait l'avoir perdue

En descendant par cinq vagues dans les trois racines du workspace, la Citadelle est ressortie partout : articles, handoffs, un agent .claude. Le code, lui, était absent du disque. On l'a classée « prototype dormant, éparpillé », puis « idée perdue ».

En cherchant pourquoi, la vérité est apparue : elle n'était pas perdue — elle avait déménagé. Un dépôt dédié, FGDidou/VFG_Citadelle-private, créé les 6-7 juillet, avec un développement réel (V1.1 → V3.3, Playwright, check:secrets) jusqu'au 18 juillet, PR #14.

Entre-temps, le 8 juillet, un nettoyage de CI avait supprimé son module jumeau du blog — « qualifié de projet sans rapport » — par un agent qui ignorait qu'un verdict de FG était en attente. Le verdict fut tranché de fait, par quelqu'un qui ne savait pas qu'il tranchait. C'est documenté noir sur blanc dans nos propres handoffs ; ce n'est pas une métaphore.

Le clone récupéré :

gh repo clone FGDidou/VFG_Citadelle-private VFG_Citadelle

2. Deux bugs, deux leçons

Le bug de la lettre cachée

npm test → 63/65. Deux tests rouges, tous les deux dans le constructeur de la démo autonome. Le message était précis :

Cannot use import statement outside a module — bloc <script> n°6 ne parse pas.

Le build retire les imports des sources avec des expressions de ligne ; le checkout était en CRLF (Windows, core.autocrlf=true, pas de .gitattributes). Le \r en fin de ligne fait échouer $ et le . d'une regex — et les import … from … survivent dans le HTML, qui ne se parse plus.

La correction est à deux étages :

  1. Dans le code — normaliser \r\n → \n avant les regex (durable, indépendant du checkout).
  2. Dans le dépôt — un .gitattributes avec eol=lf (préventif, pour la machine suivante).

→ 65/65.

C'est la même famille que le « bruit CRLF » qui nous faisait lire worktree modifié là où rien n'avait changé. Ce workspace a un contentieux avec les fins de ligne.

Le bug du chemin déduit — le vrai sujet

Serveur lancé, page ouverte… et 17 projets sur 19 en brouillard. La carte s'affiche, mais presque toutes les cités sont invisibles :

👁 2 visible(s) · 🌫 17 en brouillard

Or ce symptôme n'était pas neuf : un article du 26 septembre notait déjà « Citadelle en brouillard (present=false partout), garnison 0/8 ». Le brouillard était chronique.

La cause, dans citadelle/lib/paths.mjs :

const workspaceRoot = path.resolve(blogRoot, '..')   // = le PARENT du repo blog

La Citadelle résolvait le workspace comme le parent de sa propre position. Tant qu'elle vivait dans RAPPORT-EXPERIENTIEL/citadelle/, ce parent était D:\VFG_PT__ — le workspace. Une fois dans D:\GitRepos\VFG_Citadelle, le parent devient D:\GitRepos — où les repos VFG n'existent pas (sauf le blog). D'où le brouillard.

Le repo prévoyait ce cas — ce n'est pas un bug, c'est un défaut de configuration :

options.workspaceRoot || env.CITADELLE_WORKSPACE_ROOT || path.resolve(blogRoot, '..')

Il suffit de déclarer la racine :

$env:CITADELLE_ROLE='local'
$env:CITADELLE_WORKSPACE_ROOT='D:\VFG_PT__'
node citadelle/server.mjs

→ brouillard levé : 2 visibles → 15 visibles, mesuré avant/après. Santé du Royaume 79/100.

3. Ce que la Citadelle voit maintenant

Une fois branchée sur la bonne racine, la carte se remplit — et elle lit la vérité : STATUS.md + git de chaque repo.

15 visibles / 4 en brouillardles 4 absents sont les absences légitimes (projets optionnels, non clonés)
Santé 79/1006 cités saines, 9 en attention
Front le plus chaudFG_CleanDaMatrix
Working trees salesVFVFGPT, VFG_Hero, ChataigneProjects, RAPPORT-EXPERIENTIEL — signalés immédiatement

Ces quatre working trees sales ne sont pas un défaut : c'est le travail chaud, en cours, d'un autre agent sur la racine active. La Citadelle a fait son travail : elle a vu l'état réel sans qu'on le lui dise. La preuve d'usage est faite.

4. La leçon qui dépasse la Citadelle

Un outil qui résout un chemin relativement à sa position se casse quand on le déplace. Le chemin canonique doit être déclaré, jamais déduit.

C'est la même famille d'erreur que le reste de l'état des lieux du jour :

  • les junctions de tiers : le chemin « canonique » (_live/VFGate) est en fait un pointeur vers un dossier racine — deux adresses pour un dépôt ;
  • les owner_repo: null dans le manifeste : l'appartenance déclarée contredit le remote réel ;
  • le blog en quatre copies : une seule a le script de publication.

Partout : quand deux adresses coexistent, l'une ment. Et quand une adresse est déduite (de la position, du parent, du voisinage) au lieu d'être déclarée, le déplacement la fait mentir silencieusement.

5. Où on en est

La Citadelle tourne. Elle n'est pas rebranchée sur des données périmées : elle lit l'état du jour. Il reste trois gestes, tous à décider :

  1. Déclarer la racine durablement — .env local (CITADELLE_WORKSPACE_ROOT), ou réserver le port :5460 via le SSOT.
  2. Pousser (ou non) le fix CRLF — commit local 916b2a7, en attente.
  3. Instruire la divergence historique — un clone, ailleurs, porte 4 commits non poussés dont un fix critique ; ils n'ont jamais rejoint le canonique.

6. Moral

On a passé une journée à croire que le Royaume était vide. Il ne l'était pas : il était plein de choses belles, bâties puis silencieuses — un jardin sans portier, une Citadelle endormie qui respirait encore, des cartes de sortilège, huit chaînes qui n'attendaient qu'un pont.

Ce qui manque n'est pas le travail. Il est fait, dormant, éparpillé. Ce qui manque, c'est le fil qui relie.

Et parfois, le fil rompu est un simple chemin qu'on avait déduit au lieu de le déclarer.


Constats mesurés et rejouables le 2026-10-01. npm test → 65/65 · GET :5460/api/etat → 15 visibles / 4 brouillard · citadelle/lib/paths.mjs → résolution parent(blogRoot). Détail complet : out/CITADELLE-REACTIVEE.md.

source markdown

Concepts de cet article

CitadellehandoffworktreeSSOTMCP

Partage le plus de concepts avec