Commit Graph

27 Commits

Author SHA1 Message Date
Sylvain Duchesne f875047099 fix!: la garde circulaire disparait, et une nouvelle tentative se fait au nom de qui a ete refuse
Troisieme tour de revue adversariale, trois constats, tous reproduits avant
correction.

1. La garde etait CIRCULAIRE, et c'etait structurel. `namedDocumentsReachable`
   demandait si la capacite est DETENUE. Pour un document en store public, le seul
   canal qui puisse jamais la deposer est `fetchReadCap` - l'appel meme que la
   garde retenait. Elle attendait une reponse que seule l'action qu'elle bloquait
   pouvait produire, et toute cette classe restait irrecuperable.

   La bonne question n'est pas une meilleure garde, c'est de RETENTER. Les deux
   facons d'etre refuse se reparent par des choses opposees, et le memo les
   distingue deja : un echec n'est deliberement pas memoise, donc une nouvelle
   tentative redemande vraiment au reseau - c'est la reparation de cette classe,
   pas un cout a eviter ; une absence est memoise, donc une nouvelle tentative ne
   demande a personne et coute un instantane, jusqu'au jour ou la capacite arrive
   d'ailleurs, seule chose qui repare celle-la. La garde est supprimee : le module
   est plus petit qu'au tour precedent.

2. La reouverture faisait un ACCES sous la mauvaise identite. Republier REFILTRE
   une requete existante ; rouvrir EMET un abonnement et une requete au store
   public pour un document que cet abonne a nomme. C'est un acte neuf, pas un
   ancien qui ressort, et l'etat final etait `isSuccess` avec `data: []` pour un
   document illisible - le mensonge que cette tache supprime, par la porte du
   correctif. `refusedFor` retient QUI a ete refuse ; on ne retente que tant que
   c'est encore lui le connecte.

   Etabli plutot qu'affirme : une application ne peut pas changer d'identite en
   cours de session. `ensureIdentity` est le seul appel publie qui en etablit une,
   et `resolveIdentity` commence par `getCurrentUser()`. Corrige quand meme.

3. `Promise.all` court-circuite a la premiere rejection ARRIVEE, et un fetch qui
   rejette n'attend pas la barriere de synchronisation : il double un refus portant
   sur un document nomme avant lui. Le comportement est corrige plutot que le
   commentaire - `allSettled` puis parcours dans l'ordre du scope.

Et le quatrieme controle e2e est retire, pas repare : il passait avec toute la
machinerie de reprise supprimee. Un controle qui ne peut echouer pour aucune
regression de ce qu'il garde se lit comme de la couverture et vaut moins que rien.
2026-09-21 16:28:24 +02:00
Sylvain Duchesne aecb7cf2e8 test: dire exactement ce que le controle e2e mesure, qui est moins qu-il n-y parait
Le controle « une cle qui tombe pour un AUTRE document laisse le scope refuse »
mesure l'ISSUE, pas le ciblage : il ne separe pas « aucune reouverture n'a ete
tentee » de « une a ete tentee et refusee a nouveau », les deux finissant au meme
endroit. Le ciblage se mesure au compte de notifications, dans la suite unitaire.

Nommer ce qu'un controle vert prouve est toute la lecon du tour qui a livre cette
barriere sans aucune couverture de scope nomme.
2026-09-21 16:06:26 +02:00
Sylvain Duchesne f36ed5c164 fix!: un scope nomme refuse se rouvre quand la cle arrive, et la barriere cesse d-etre serie
Revue adversariale : la barriere livree au tour precedent rendait le refus
TERMINAL. Le signal du trousseau s'ecrit `if (query !== null) publish(...)`, parce
qu'avant la barriere il n'y avait qu'une seule raison de n'avoir pas de requete -
rien n'avait encore ete tente - et qu'une cle qui arrive ne pouvait changer que ce
qu'une requete OUVERTE avait le droit de montrer. La barriere en a ajoute une
seconde : elle abandonne AVANT que la requete existe, donc le seul canal qui fait
converger une cle tardive passait a cote de l'etat qui en avait le plus besoin.
Une page qui s'abonne pendant que son trousseau se restaure, ou un document
partage sous les yeux de son destinataire, publiait `isError` et y restait. Ce
n'est pas une surface plus stricte, c'est une pire : echanger un vide mensonger
contre une erreur bloquee ne repare rien, et cela casse une garantie que ce paquet
publie.

Le signal rouvre donc un scope refuse, et seulement quand le refus est leve
(`namedDocumentsReachable`). Le garde-fou porte autant que la reouverture :
rouvrir a chaque changement de trousseau rejouerait la barriere pour chaque cle
qu'une connexion depose, redemanderait au reseau tout document dont le
telechargement avait ECHOUE - un echec n'est deliberement pas memoise - et
republierait la meme erreur a chaque abonne. La variante indiscriminee casse deux
tests, dont celui de demontage qui preexistait.

La barriere passe en parallele. Elle etait serie, donc N documents qui ne poussent
jamais de `State` coutaient N replis bornes, 8s chacun en production. Les refus
restent lus dans l'ordre du scope apres coup.

Et ce qui a laisse passer les deux : l'e2e ne parcourait pas ce chemin. Les deux
journeys `useShapeQuery` lisent `{graphs: "did:ng:i"}`, donc 43/43 n'a jamais rien
prouve sur la barriere. Quatre controles ajoutes sur un scope NOMME, contre le
vrai broker : la proprietaire lit son document, un porteur de rien recoit
`isError` et jamais un succes vide, un document PUBLIC s'ouvre pour lui depuis la
seule reference via la requete de la barriere, et une cle qui tombe pour un AUTRE
document laisse le scope refuse en place.
2026-09-21 15:57:56 +02:00
Sylvain Duchesne aa38b37f33 chore: T01.j porte son enumeration et son resultat
L'enumeration a ete ecrite avant le code, comme demande : les quatre sites
d'appel, ce que chacun fait aujourd'hui quand la capacite ne peut pas etre
obtenue, le cas inerte, et la liste de ce qui doit rester un succes. Le resultat
consigne le choix, les quatre options ecartees avec leur raison, ce qui a casse
et ce que ces tests affirmaient vraiment, et les deux bug_ qui ne se ferment pas.
2026-09-21 15:24:40 +02:00
Sylvain Duchesne 6cd96b0182 feat: pnpm partout et les deux plages trop larges deviennent une tache 2026-09-21 14:58:28 +02:00
Sylvain Duchesne 5cbcabecf2 chore: T01.i est close, et la doc perimee d-open-repo passe a T01.j 2026-09-21 14:45:14 +02:00
Sylvain Duchesne 6c1d281755 T01.i is close: ensureReposOpen dead, example typechecks, bun store gone
The example's real bug was a missing satisfies clause widening
NoteShape's valType, not the pnpm-workspace.yaml gap the lead pointed
at - that gap was real too and got fixed, but for a different reason
(examples/notebook shared node_modules/.bun with the store this task
also deletes).
2026-09-21 14:44:09 +02:00
Sylvain Duchesne d62d23c686 chore: T01.k passe apres T01.j, elles touchent les memes annotations 2026-09-21 14:34:40 +02:00
Sylvain Duchesne 55c918dd4b feat: l-ecart entre l-arbre cite et la version compilee devient une tache 2026-09-21 14:34:29 +02:00
Sylvain Duchesne 5d2899157f chore: T01.h est close, et sa trouvaille sur pnpm alimente T01.i 2026-09-21 14:31:56 +02:00
Sylvain Duchesne 6b278b404e chore: T01.h est close - les paquets etaient deja a jour, la doctrine non
Les quatre paquets @ng-org sont a leur derniere version publiee : le
refresh ne deplace rien (verifie par dist-tag, liste complete des
versions et pnpm outdated). Le travail reel etait la reconciliation
laissee par le refresh precedent.

Deux constats consignes dans le Result :

- l'arbre etait installe par bun, pas par pnpm, avec un store .bun
  portant encore web alpha.13, shex-orm alpha.8 et alien-deepsignals
  alpha.11 a cote des courants ; danger d'instance unique latent,
  reconcilie par une reinstallation pnpm
- le checkout epingle de nextgraph-rs (213338f6) declare orm alpha.18,
  soit trois versions derriere les paquets compiles : toute citation de
  source decrit une version que ce depot n'utilise plus

Piege a retenir : web, shex-orm et alien-deepsignals publient aussi un
0.1.2 nu, que semver classe AU-DESSUS des alpha alors qu'il date de
2025. Ce sont les pins exacts qui l'ecartent.

Quatre portes vertes, plus les mesures live : orm-live-read 5 passed /
0 failed (pret en 13ms), suite e2e polyfill 43 passed / 0 failed.
2026-09-21 14:30:11 +02:00
Sylvain Duchesne ddb3d0552d feat: la chaine de l-echec lu comme une absence devient une tache a part entiere 2026-09-21 14:27:10 +02:00
Sylvain Duchesne 7599004fc3 chore: les trois suites de T01.f deviennent une tache 2026-09-21 14:17:42 +02:00
Sylvain Duchesne 2588dae24e chore: T01.f est close, le digest porte le fait RepoNotFound 2026-09-21 14:16:25 +02:00
Sylvain Duchesne 53673a9893 chore: T01.f est close - readUnion retire et la lecture par document documentee 2026-09-21 14:12:30 +02:00
Sylvain Duchesne d0ea043a5b feat!: la famille ORM est publiee enveloppee, et le ng publie cesse de rendre des promesses 2026-09-21 12:38:17 +02:00
Sylvain Duchesne 2aac703784 chore: la suppression de readUnion est bloquee par un manque de notre cote 2026-09-21 12:17:15 +02:00
Sylvain Duchesne 77e78ec81d feat!: useShapeQuery lit par la requete de forme du SDK 2026-09-21 11:41:31 +02:00
Sylvain Duchesne a5e553e65b chore: readUnion a un consommateur declare, et son fake masque la rupture 2026-09-21 11:34:20 +02:00
Sylvain Duchesne d440639616 chore: aucun element du SDK n'est republie tel quel 2026-09-21 11:07:23 +02:00
Sylvain Duchesne 82769c4939 chore: les paquets ng-org rattrapent le deploiement, et la lecture vive demarre 2026-09-21 11:02:08 +02:00
Sylvain Duchesne 4a4e6af337 chore: ng-e2e-helpers suit alpha.14, et la mise a jour des paquets devient une tache 2026-09-21 10:52:07 +02:00
Sylvain Duchesne d0ca5c5d41 feat!: useShapeQuery prend le Scope du SDK, et un store se nomme par sa reference 2026-09-16 16:47:09 +02:00
Sylvain Duchesne ee9319f89b docs: ce que l'ORM offre pour ecrire et supprimer, et la vraie cause du useShape mort 2026-09-16 16:04:22 +02:00
Sylvain Duchesne dd874bb9c4 feat: une cible annoncee mais pas encore ecrite a desormais sa categorie 2026-09-16 15:33:14 +02:00
Sylvain Duchesne 1a4857cb75 chore: les arbitrages de la session entrent dans les taches 2026-09-16 15:22:05 +02:00
Sylvain Duchesne eb8a7163a2 chore: l'arbre de travail pour l'alignement de la surface 2026-09-16 12:20:57 +02:00