tooling(validate): nettoyage SingletonLock + @multibrowser réactif @wip (limite wallet-partagé)

- validate.ts : `cleanSingletons()` retire SingletonLock/Cookie/Socket avant
  polyfill:e2e (et à la rotation) → fiabilise polyfill:e2e (fini le faux rouge
  ProcessSingleton). @multibrowser lancé en `@multibrowser and not @wip`.
- e2e-multibrowser : le scénario réactif « Un participant apparaît réactivement »
  passe @wip, commentaire d'en-tête expliquant la LIMITE : en wallet-partagé A et B
  partagent UNE identité NG → B voit l'événement de A comme possédé → son
  owner-materializer écrit le doc de A → StorageError. PAS un bug produit (prod =
  wallets distincts). Vrai fix = isolation distinct-wallets (chantier T02.d/g).
  Réserve : ce scénario était vert (517045c) ; à re-vérifier lors de l'isolation
  distinct-wallets (peut masquer une interaction phase-B).

Baseline validate visé : vert sauf ce @multibrowser documenté.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sylvain Duchesne
2026-07-10 17:17:18 +02:00
parent 7dab6e44e2
commit 0fc8479e22
2 changed files with 50 additions and 12 deletions
@@ -57,6 +57,23 @@ Fonctionnalité: Validation e2e multi-navigateurs des nouvelles features (T02.f)
# A (poussé par doc_subscribe sur le doc public de l'événement) montre
# participantCount === 1 et un participant "inconnu".
# @wip — LIMITE STRUCTURELLE wallet partagé (pas un bug produit)
#
# CAUSE RACINE : en harness @shared-wallet, A et B partagent UNE SEULE identité
# NextGraph. `listMyEntityDocs(username, 'public')` retourne les mêmes docs dans
# les deux contextes Playwright. Le owner-materializer de B détecte donc les
# événements créés par A comme "possédés" et tente d'écrire `participantCount` sur
# le doc de A. Le verifier de B n'a pas ouvert ce repo (il a été créé dans la
# session de A) → le broker retourne `StorageError` sur `sparql_update`. La
# matérialisation échoue côté B, et le compteur ne converge pas dans le délai du
# test. En production, A et B sont des identités distinctes (wallets séparés) et B
# ne possède jamais les événements de A — ce conflit n'existe pas.
#
# FIX ATTENDU : wallet isolation réelle (distinct-wallets, T02.d/T02.g) — chaque
# navigateur a sa propre identité NG ; `listMyEntityDocs` ne retourne que les docs
# de cette identité ; le owner-materializer est naturellement borné à son propre
# wallet. Jusqu'à cette migration, ce scénario reste @wip documenté.
@wip
Scénario: Un participant apparaît réactivement dans l'autre navigateur sans reload
Étant donné un navigateur "A" avec le wallet partagé
Et un navigateur "B" avec le wallet partagé