test: reconnexion « relit ses propres données » — VERT, retrait de @wip (bug résolu)

Le bug de reconnexion (page fraîche même identité relit vide) est RÉSOLU côté lib
(résolution de compte déterministe + dé-dup des ensureAccount concurrents). Le
scénario passe 2/2 sur broker réel → retrait de @wip (redevient @data bloquant),
en-tête corrigé. `storeRegistry.ts` : config `provisionRetry` (retry anti-fork).

Non-régression vérifiée : isolation + inscription verts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sylvain Duchesne
2026-07-10 11:30:13 +02:00
parent f366ee29a7
commit 91ee3567aa
2 changed files with 26 additions and 15 deletions
@@ -1,27 +1,31 @@
# language: fr
@EVENT @priority-1 @data @wip
@EVENT @priority-1 @data
Fonctionnalité: Reconnexion d'une même identité sur le wallet persistant
En tant qu'utilisateur qui, sur le MÊME wallet physique, ouvre une PAGE FRAÎCHE
(nouveau login broker, session fraîche) sous le MÊME identifiant qu'avant,
Je dois relire MES PROPRES données (mon événement, ma participation)
Afin que rien ne disparaisse à la reconnexion.
# Régression de RECONNEXION (distincte de l'isolation deux-identités). @wip : le
# défaut est RÉEL mais non encore corrigé ce scénario le documente et échoue
# tant que le fix n'est pas complet.
# Régression de RECONNEXION (distincte de l'isolation deux-identités). CORRIGÉ :
# ce scénario passe désormais sous broker réel (2/2 vérifié).
#
# SYMPTÔME observé (broker réel, mesuré) : une identité A crée E + s'y inscrit
# sur la page principale ; une PAGE FRAÎCHE pour la MÊME identité A (même wallet,
# nouveau login session verifier fraîche) relit VIDE (home=[],
# isParticipating=false, count=0). La page fraîche DOIT retrouver E, sa
# participation, et un count autoritatif de 1.
# SYMPTÔME (broker réel) : une identité A crée E + s'y inscrit sur la page
# principale ; une PAGE FRAÎCHE pour la MÊME identité A (même wallet, nouveau
# login session verifier fraîche) relisait VIDE (home=[], isParticipating=false,
# count=0). La page fraîche retrouve maintenant E, sa participation, et un count
# autoritatif de 1.
#
# MÉCANISME (sous investigation, à confirmer sous broker) : la lecture ancrée à
# froid tape des repos pas encore ouverts. Le fix lib `open-repo` fait remonter
# le PROTECTED (participation) au cold-start, mais PAS l'accueil PUBLIC :
# `readScopeIndex` de l'index de scope public rend 0 (observé même côté écrivain
# même-session) alors que le code d'index de la lib est scope-symétrique cause
# exacte encore à mesurer (broker requis).
# CAUSE : à froid, plusieurs lecteurs (watchShape public/protected + effet owned-
# events) appelaient `ensureAccount(A)` en parallèle AVANT sync du shim chacun
# lisait 0 ligne et PROVISIONNAIT un nouveau jeu de docs de scope (fork de compte
# par lecteur). `canonicalDoc` faisait alors choisir au lecteur frais le docProtected
# lexicographiquement-min celui où l'écrivain avait joué joinEvent readScopeIndex
# vide. FIX (lib) : `ensureAccount` dé-doublonne les provisions concurrentes (map
# in-flight par clé de compte) une seule provision, écrivain et lecteur convergent
# sur le même docProtected canonique. Complété par le heal cold-start de
# `discovery.readIndex` (ouverture du repo d'index avant lecture ancrée).
# Mesuré (fresh page, broker réel) : partProt converge isSuccess n=1, pub isSuccess
# n1 ; userProt reste isSuccess n=0 (aucun profil écrit dans ce scénario attendu).
@data
Scénario: Une page fraîche pour la même identité relit ses propres données
+7
View File
@@ -53,6 +53,13 @@ configureStoreRegistry({
},
// The app maps its username handle to the identity id the lib keys on.
normalizeId: normalizeUsername,
// Anti-fork bounded retry (real broker): on a fresh page over the persistent
// wallet (reconnection under the SAME identity) the shim may not be synced when
// the first read fires → 0 rows. Without this, the registry would provision a
// NEW account (a fork), so the fresh page reads its own data as empty. The
// bounded backoff waits the sync-lag window out before concluding "genuinely
// new". Bounded (never an open-ended broker poll).
provisionRetry: { attempts: 8, baseMs: 150, maxStepMs: 2000 },
});
// --- Re-export the lib's account record + registry surface (unchanged API) ---