Files
ng-eventually/examples/notebook
Sylvain Duchesne 49b046268e docs(contract): le contrat décrit l'API, et rien d'autre
Récriture complète de `contract_sdk-surface.md` sur le cadrage du propriétaire du projet :
**le contrat dit ce que le SDK met à disposition, point.**

Ce qui en sort, et pourquoi ça n'y avait pas sa place :

- **tout état d'implémentation** — chiffrement, confidentialité, valeur de remplacement,
  ce qui est émulé, ce qui n'est pas encore fait. Le lecteur est un agent qui développe
  une application appelante : s'il lit qu'une chose est provisoire, il conçoit des
  compensations — sa propre couche de chiffrement, un choix de ne pas stocker telle
  donnée, un avertissement d'interface — toutes fausses et toutes à retirer. Il doit
  pouvoir considérer que ce SDK **est** celui de NextGraph ;
- **la fabrique** — « polyfill », « portefeuille partagé », « multi-utilisateurs », la
  migration, ce que l'application supprimera un jour, les écarts par rapport à la cible ;
- **l'argumentaire** — ce que le modèle « permet », ce que telle règle « achète », la
  confidentialité composable. Un appelant a besoin de savoir qu'une référence rendue ne
  porte pas de clé, pas de savoir ce que ça lui apporte.

Ce qui entre : les **trois obligations de déploiement**, vérifiées dans le code — servir un
`.ngw` depuis son bundle et le passer à `configure`, être ouverte via la redirection du
broker, appeler `ensureIdentity()` dans un contexte navigateur avant de rendre — et trois
clauses contraignantes qui manquaient : l'identifiant rendu est **opaque**, le préfixe
`urn:ng-eventually:` est **réservé sur les sujets**, et le placement recommandé est un
document par entité métier, plusieurs objets dans un document restant permis.

`## Guarantees` devient une suite d'énoncés plats. `## Non-guarantees` ne liste que des
**absences de capacité** — pas de nom d'affichage, pas de révocation, rien par lecteur sur
un document en store public, pas d'écriture déléguée — jamais un manque par rapport à
autre chose.

L'application d'exemple n'affiche plus l'identifiant comme un nom : elle le montre pour ce
qu'il est, un identifiant technique. C'était exactement ce que la clause « opaque »
interdit, dans le fichier censé montrer le bon geste.

202 tests, typechecks propres, `lint` sans erreur. 148 → 135 lignes.
2026-08-10 15:03:08 +02:00
..

Notebook — the library's example application

A minimal application written against @ng-eventually/sdk, in plain DOM.

It exists for two reasons, and the second is the one that matters.

It shows how to use the library. Every call in app.ts is what a real consumer writes. There is no test scaffolding, no privileged import, no reaching into the library's internals — it resolves @ng-eventually/sdk as an external consumer does. If something reads awkwardly here, it reads awkwardly for everyone.

It is what the applicative e2e suite drives (packages/sdk/e2e/notebook.ts, bun run test:e2e:app). The other suite talks to a bag of methods on window.__sdk, which proves the functions run but never that an application can be written with them — and that gap shipped a real defect once: a document's inbox was green in tests and unusable in practice, because the harness handed an address across an identity boundary through a variable, something no application can do. Here each identity is its own browser page, and the only values that cross between them are the ones that cross in life: a note's reference, copied off one screen, and an identifier typed into a field.

It has already paid for itself: writing it surfaced that UnionSubject returned string where the values are always document references (so a consumer had to cast whatever it had just read before passing it back), and that the access gate normalized what a user typed but not what the URL carried.

What it exercises

Signing in, writing notes by scope, listing one's own, reading a note from its bare reference, handing a reader the key to a protected note, opening a note for messages, leaving a message on someone else's note, and reacting to changes.

The four journeys the suite runs, and what each proves:

Journey What it proves
Bob reads Alice's PUBLIC note from its reference alone A public store serves its notes' keys — a bare reference is enough, and no key ever crosses
Alice's PROTECTED note stays shut until she shares it The same gesture, the opposite outcome, decided by where the note sits and not by what was sent
Bob leaves a message on Alice's note, and only Alice reads it A depositor FINDS the address from the note itself; depositing grants no reading
Each actor's list holds their own notes The boundary, seen from the only place that matters: the screen

It has also found three defects of its own, each one the harness could not see. The first turned out to be a LIBRARY defect rather than an application one: the connection work had to be awaited at sign-in, or a note just shared with you read as unreadable — so ensureIdentity now awaits it, and connectedUser left the published surface. The other two were the application's: a stale answer stayed on screen beside a fresh question, and changing the scope did not refresh the list.

Running it

cd packages/sdk && bun run test:e2e:app builds it, serves it, and drives it against the real broker. To open it by hand you need a wallet: serve the folder with a bundled app.js and a /shared-wallet.ngw, and set __NOTEBOOK_WALLET_PASSWORD__.