fix(client): durcir le cold-start du shim — ensureRepoOpen(anchor) avant lecture/écriture

Défensif : loadShim/resolveAccount/ensureAccount ouvrent l'anchor (private-store-root)
avant de lire/écrire le compte shim, comme le fait déjà readScopeIndex. Robustesse
same-session si l'anchor est là-mais-pas-encore-souscrit.

NB (vérifié nextgraph-rs) : sur le login broker normal, le bootstrap charge le
private-store dans self.repos AVANT de rendre la session à JS → un wallet FRAIS
retourne 0 rows (pas RepoNotFound) et provisionne. Il n'existe AUCUN primitif JS
pour ouvrir un repo *inconnu* : ce heal n'est pas un remède à un store non
bootstrappé (limite NextGraph), juste une robustesse d'ouverture same-session.

Tests : cold-start-anchor.test.ts (rouge-avant/vert-après unit) ; harness e2e
repro-fresh-wallet (mint un wallet neuf par run — comble le trou "aucun test de
démarrage à froid sur wallet vierge"). Fakes anti-fork/watch-shape honorent
désormais la barrière first-State dont dépend le heal. e2e réel 42/42.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sylvain Duchesne
2026-07-13 15:06:30 +02:00
parent 078d675bbf
commit 3046ead08f
7 changed files with 473 additions and 6 deletions
+7
View File
@@ -68,6 +68,13 @@ function makeFake(opts?: { holdState?: boolean }) {
const hold = opts?.holdState ?? false;
// Nuris whose barrier `State` has been released (auto-fire on future subscribe).
const released = new Set<string>();
// The shim ANCHOR (private-store-root) is ALWAYS loaded/synced on the real broker
// (the store repo is bootstrapped at connect), so its barrier `State` is always
// available. `resolveAccount`/`ensureAccount` now open it (the cold-start heal)
// before touching the shim — pre-release it here so `holdState` (which gates the
// per-ENTITY docs the tests control) never blocks the anchor open. This mirrors the
// real invariant the production heal relies on.
released.add(`did:ng:${SESSION.privateStoreId}`);
let releaseEverything = false;
const doc_create = mock(async () => `did:ng:o:doc${++docCounter}`);