Les quatre paquets @ng-org sont deja a leur derniere version publiee
(web alpha.14, orm alpha.21, shex-orm alpha.9, alien-deepsignals
alpha.13) : le refresh ne deplace rien. Ce qui restait faux, c'est la
doctrine, laissee en arriere par le refresh precedent.
Le point de fond : le checkout epingle de nextgraph-rs (213338f6)
declare orm alpha.18, donc la source citee est TROIS versions derriere
les paquets contre lesquels ce depot compile. La ou les deux divergent,
les leaves nomment desormais les deux.
Faits corriges, tous verifies dans node_modules :
- les versions installees annoncees en tete de leaf (alpha.19/13/11)
- OrmSubscription est renomme RdfOrmSubscription dans alpha.21, fichier
compris (connector/RdfOrmSubscription.ts)
- alpha.21 exporte removeObject(graphNuri, subjectIri), absent de la
source ; sa propre documentation se contredit sur sa portee
- getOrCreate prend un RdfOrmConfig, plus un Scope nu, et l'instance
gagne mode/isReady/addChangeListener/nextPage/previousPage
- Scope.graphs est REQUIS dans alpha.21, et les deux axes lisent [] en
sens INVERSE : graphs [] = ensemble vide, subjects [] = aucun filtre.
La table le dit explicitement, c'est le piege deja paye une fois
- la lecture ORM live DEMARRE contre le deploiement (5 passed, 0 failed,
pret en 13ms) ; le lien mort vers bug_useshape-live-read-needs-a-newer
-broker disparait, ainsi que le "exit non-zero attendu" de la suite
Ce qui n'est PAS affirme : que le where/orderBy/pageSize d'alpha.21
atteigne le moteur. A 213338f6 start_orm construit encore son config a
partir de json!({}) derriere un TODO, donc la richesse est exprimable au
niveau 3 et jetee au niveau 1. Non mesure, donc non ecrit.
4.1 KiB
type, summary
| type | summary |
|---|---|
| knowledge | Which suite answers which question, what a batch costs, and why two runs must never overlap |
What each suite judges
The polyfill suite exercises the published surface against the real broker: capabilities, reads, inboxes, reactivity. It is the one that judges whether the emulation behaves like the target.
The applicative suite drives the example application through a browser, as a person would — several identities, several pages, assertions on what is on screen rather than on what the library returns. It judges whether an application built on this package actually works, including the sign-in a person really performs.
The reactivity suite isolates document subscription.
The ORM live-read measurement asks one question of the deployment rather than of this package: does a live useShape read actually start. It is the only runner that imports @ng-org/orm — an optional peer bun install does not fetch — which is why it stands apart from the polyfill suite instead of inside it: a checkout without the ORM must still be able to run the other three. It exited non-zero for as long as the deployed broker and the published client packages disagreed on orm_start_graph; since the packages caught up on 2026-09-21 it is GREEN, and a red run now means they have drifted apart again.
A unit suite cannot replace any of the first three, and none of them replaces the unit suite: they are slow, they depend on live external services, and they cannot enumerate a case space.
What a batch costs, and why
Every run mints its own physical user by driving the wallet application's real interface, then discards the previous one. That is deliberate — identities must not leak between runs — and it puts a floor under every run that no test filter can remove.
Consequence worth knowing before optimizing anything: the setup runs before any journey, so filtering journeys saves journey time only — the floor stays.
Two runs may overlap — and that was not free
They once could not: the profile was a single shared directory, and a run starting while another was alive destroyed it, which then failed in a way that read as a product defect. Several measurements were lost to it.
Now each run gets its own profile directory and kills the browser holding it when it ends, so concurrent runs — including a consuming application's suite, from its own checkout — are independent by construction. A lock once guarded the shared directory; it treated the symptom, and removing the sharing removed the need. Prefer that shape whenever two runs contend: make the contended thing per-run rather than serialising access to it.
A bound must be larger than the sum of what it encloses
An enclosing deadline shorter than its own steps can only ever fire first, so every failure underneath it reports the enclosing name and none of them can name a cause. The sign-in bound sat at 180 s over steps totalling 270 s, and for days every failure said the same four words while the real step stayed anonymous. Days went into looking for a cause the harness was structurally incapable of reporting.
So: compute an enclosing bound from its parts rather than picking a number, and size every leaf bound from a measured healthy duration recorded beside it. A bare figure teaches nothing and rots without anyone noticing; a figure with its measurement lets the next reader tell a generous bound from a tight one.
What a run must report whatever happens
Declare the journeys and their checks before anything can fail, so a run reports the same number of rows every time. When the count itself moves with the failure — journeys dying and taking their unreported checks with them — two runs are no longer comparable, and a shrinking total reads like a smaller problem instead of a bigger one.
The related trap that made it self-perpetuating: discarding the profile was once conditioned on a marker written at the end of a batch, so a run killed before writing it left a profile the next run happily reused — and inherited its breakage. Discarding now keys on the profile itself.