--- name: ticket56-visibleelsewhere-derives-from-layout description: Fix frontend du sélecteur d'agent : la désactivation « visible ailleurs » doit venir du layout courant, pas du dernier nodeId du live registry. metadata: type: reference --- Bug #56 : agent X affiché en cellule A → A bascule sur Y → X désactivé (« visible ailleurs ») en cellule B alors que X n'est plus affiché nulle part. Cause : le live registry garde X→nodeId A même après le swap ; `LayoutGrid.visibleElsewhere` lisait `live.nodeId` comme « affiché ici ». Fix (frontend pur, ne tue pas la session) dans `frontend/src/features/layout/LayoutGrid.tsx` : - `visibleElsewhere(candidate)` dérive du **layout courant** : truthy uniquement s'il existe une feuille visible ≠ cellule courante avec `leaf.agent === candidate`. Retourne `{ nodeId }`. - `backgroundLive` utilise `!visibleElsewhere(candidate)` au lieu de `!visibleNodeIds.has(live.nodeId)` ; garde `live.nodeId === id` (anti-boucle self-launch). - onChange du select : même dérivation ; sélection inchangée (attachLiveAgent si sessionId sinon setCellAgent). - Prop `visibleNodeIds` supprimé (devenu mort) de tout le threading LayoutGrid→NodeView→Split/Grid/Leaf. Invariant préservé : agent réellement épinglé dans une cellule visible reste NON sélectionnable ailleurs. Piège de test : un test qui mocke `listLiveAgents` avec un nodeId visible mais **sans** épingler l'agent dans ce leaf ne désactive plus rien — il faut `setCellAgent` réel. Tests dans `singletonAgent.test.tsx` (describe « ticket #56 » + ajustement R0d). Suite frontend : 706 verts.