refactor: renommer client → sdk, et fusionner les deux portes en une
Deux mouvements de surface, aucun changement de comportement. **`packages/client` → `packages/sdk`, `@ng-eventually/client` → `@ng-eventually/sdk`.** « client » ne disait rien : ce paquet EST le SDK que l'application appelle, et c'est tout ce qu'elle appelle. L'ancien nom reste comme mot-clé de recherche dans `docs/source-layout-by-fate.md` et le tableau des paquets du README. **Une seule entrée.** L'entrée `./polyfill` disparaît ; ses symboles applicatifs — `configure`, `configureStoreRegistry`, `setCurrentUser`, `connectedUser` et leurs types — vivent dans un bloc `POLYFILL-ERA` de `src/index.ts`. Ce que la seconde porte portait mérite d'être nommé avant d'être retiré : *ce qu'on importe de ce chemin est exactement ce qu'on supprimera à la migration*. Une seule porte perd ce signal — rien à la ligne d'import ne distingue `configure`, qui part, de `docs`, que le vrai SDK remplace sur place. Trois choses le portent désormais : le bloc lui-même, l'inventaire d'exports de `docs/api-contract.md` (épinglé par `test/vocabulary.test.ts`, donc il ne peut pas rancir en silence), et le contrôle de vocabulaire sur les noms publiés. **Six symboles quittent la surface au passage**, et la fusion est ce qui a rendu le choix visible plutôt qu'hérité : - `getConfig` / `getStoreRegistryDeps` — câblage interne, atteint par `shared-wallet/bootstrap` ; - `resetConfig` / `resetStoreRegistry` / `resetCaps` — remises à zéro de test, atteintes par leur chemin interne, ce qui est leur raison d'être ; - le `share` direct — `inbox.share` a toujours été la même fonction, et la publier deux fois brouillait la frontière qu'elle servait à marquer. Corrections d'affirmations fausses trouvées en chemin : le contrat annonçait `isNuri` / `hasReadCap` sur la porte SDK alors qu'ils ne sont plus exportés depuis le passage au permissif en entrée (`NuriLike` validé à la porte) ; le README du paquet documentait `capFor`, `shareCap`, `getCaps` et `publishRepoLink`, dont aucun n'existe ; et le README de l'app d'exemple affirmait que la suite e2e la pilote, ce qui reste à faire. 179 tests unitaires, typecheck bibliothèque / exemple / harnais, e2e 42/42 contre le broker en ligne — mesuré une fois après le renommage, une fois après la fusion.
This commit is contained in:
@@ -70,11 +70,11 @@ The surface consequence: the *act* — obtain a link, circulate it — is the sa
|
||||
|
||||
## 5. Recommendation for the polyfill
|
||||
|
||||
The surface already exists: `linkTo(doc: NuriLike): ReadCap` (`packages/client/src/surface/placement.ts:65-77`) for the traveling value, `inbox.share(doc, toUser)` (`packages/client/src/surface/inbox.ts:285`) for directed delivery. **Keep `linkTo` — the act is the right one** — with four adjustments:
|
||||
The surface already exists: `linkTo(doc: NuriLike): ReadCap` (`packages/sdk/src/surface/placement.ts:65-77`) for the traveling value, `inbox.share(doc, toUser)` (`packages/sdk/src/surface/inbox.ts:285`) for directed delivery. **Keep `linkTo` — the act is the right one** — with four adjustments:
|
||||
|
||||
1. **Label it LEVEL-1 SHAPE in `docs/api-contract.md`.** What supports it: the `NgLink` family and its stated sharing flow, the `PermaShare` permission, the exercised object-URL and profile-QR precedents, and the PO doctrine that circulation is the only distribution. The model's own stated flows are unusable without *some* produce-a-link affordance, which is as much confidence as an unbuilt feature allows. What cannot be promised: the SDK's name for it, sync vs async (upstream link-building needs overlay + peers from the session, so async is plausible — same adapter-sized delta class as `subscribeDoc`'s sync unsubscribe), and whether the value is a NURI string or a structured link. Therefore: **the returned value is opaque**; a consumer that stores it, transmits it, and hands it back unmodified learns nothing to unlearn; a consumer that parses it does.
|
||||
2. **Fix the comment-vs-code mismatch in `linkTo`.** The docstring claims *"A protected document's key never comes out this way — it goes through `share`"*; the code returns any held cap, with no scope check. The **code** is the model-true side: `RepoLinkV0`-with-key IS the protected-document link, and sharing it out-of-band is the documented normal case (`:5059`). Align the comment: a protected link carries the key and is legitimate to circulate — with the §4 durability caveat, not a prohibition.
|
||||
3. **The recipient verb is missing.** Nothing exported ingests an out-of-band link: `learn` is reached only by inbox processing and the connection drain (`packages/client/src/surface/inbox.ts:410`, `packages/client/src/emulated-verifier/connect.ts:68`), and `getCaps()` is documented machinery (api-contract §15). The model names the recipient act precisely — open the link: load the repo from its read cap, file `AddLink` durably on the User branch, subscribe (`:5059`; `engine/repo/src/types.rs:1934-1950`; `verifier.rs:2237`). Suggested surface, same epistemic label as `linkTo`: `openLink(link: string): Promise<Nuri>` — files the cap in the emulated registers and returns the cap-less target for use in reads. Without it, path 2 has a producer and no consumer, and the multi-actor test where Bob *obtains* the document through calls (never through a shared variable) cannot be written — the exact failure mode `rules/engineering/multi-actor-tests-obtain-not-receive.md` records.
|
||||
3. **The recipient verb is missing.** Nothing exported ingests an out-of-band link: `learn` is reached only by inbox processing and the connection drain (`packages/sdk/src/surface/inbox.ts:410`, `packages/sdk/src/emulated-verifier/connect.ts:68`), and `getCaps()` is documented machinery (api-contract §15). The model names the recipient act precisely — open the link: load the repo from its read cap, file `AddLink` durably on the User branch, subscribe (`:5059`; `engine/repo/src/types.rs:1934-1950`; `verifier.rs:2237`). Suggested surface, same epistemic label as `linkTo`: `openLink(link: string): Promise<Nuri>` — files the cap in the emulated registers and returns the cap-less target for use in reads. Without it, path 2 has a producer and no consumer, and the multi-actor test where Bob *obtains* the document through calls (never through a shared variable) cannot be written — the exact failure mode `rules/engineering/multi-actor-tests-obtain-not-receive.md` records.
|
||||
4. **Do not add**: link options (expiry, audience, revoke-this-link), per-reader introspection for public documents, or any API that parses or inspects a link's insides — nothing upstream supports any of them, and each teaches a lever the model does not have.
|
||||
|
||||
## 6. The question for the NextGraph developer
|
||||
|
||||
Reference in New Issue
Block a user