feat!: la famille ORM est publiee enveloppee, et le ng publie cesse de rendre des promesses

This commit is contained in:
Sylvain Duchesne
2026-09-21 12:38:17 +02:00
parent 2aac703784
commit d0ea043a5b
21 changed files with 1102 additions and 35 deletions
+8 -6
View File
@@ -13,15 +13,17 @@
## 1. The wrapped `ng` factory — `surface/ng-proxy.ts`
```ts
// ng-proxy.ts:10
export function makeNg(): Record<string, any>;
export function makeNg(): NG;
export function wrappedNg(): NG; // the memoised one - THE instance, since 1.0.0-dev.7
```
Builds the published `ng` Proxy (consumed once, `index.ts:61`): forwards every property to the injected real `ng`, overriding `login`/`session_start` (passthrough with a shared-wallet-credentials TODO) and `sparql_update` (the emulated write-cap guard).
Builds the `ng` Proxy: forwards every property to the injected real `ng`, overriding `session_start` (passthrough with a shared-wallet-credentials TODO), `sparql_update` (the emulated write-cap guard) and, since `1.0.0-dev.7`, `graph_orm_update` (the ORM's own write door - ownership, `assertMayWrite`).
- The factory itself is **NO COUNTERPART, by design** — the target has no "wrap the SDK" step; at migration `ng` IS `@ng-org/web`'s and `makeNg` is deleted.
- The `sparql_update` guard stands in for the engine's write-permission model (`verify_perm` inside `Commit::verify`, `engine/repo/src/commit.rs:892-899`) — same analysis as `docs/api-contract.md` § 3.
- **Defect — the `login` arm fabricates a member (see Findings F1).** `@ng-org/web` has no `login`: none among the exports of `index.d.ts` (re-verified), and no `fn login` in `sdk/js/lib-wasm/src/lib.rs`. The proxy nevertheless returns a function for `prop === "login"` (`ng-proxy.ts:16-22`), so `typeof ng.login === "function"` on the wrapper while the real SDK yields `undefined` — the one place the proxy adds a member, contradicting its own header and the surface contract's "adds no member and removes none" (§ 3). Calling it throws at runtime (`ng[prop]` is undefined). **ASSUMPTION with no provenance** — no target layer names a `login`.
- `wrappedNg()` exists because the proxy now has **two** holders: `index.ts` publishes it, and `surface/lifecycle.ts` hands it to the ORM through `initNg`, so the two must be the same object. It keeps no state (every property is answered from `getConfig()` at access time), so it survives a re-`configure()` and needs no reset.
- The `sparql_update` guard stands in for the engine's write-permission model (`verify_perm` inside `Commit::verify`, `engine/repo/src/commit.rs:892-899`) - same analysis as `docs/api-contract.md` § 3. It is deliberately left on the decorative write-cap list rather than on `assertMayWrite`: the library's own REGISTERS are written through this member (`emulated-verifier/register-write.ts`), and a store document is not owned in the authorship sense, so arming it there would refuse every register write. `graph_orm_update` has no such traffic, which is why the live predicate sits on it.
- ~~**Defect - the `login` arm fabricates a member (Findings F1).**~~ **FIXED 2026-08-03**, and this bullet had outlived it: `@ng-org/web` has no `login` - none among the exports of `index.d.ts`, no `fn login` in `sdk/js/lib-wasm/src/lib.rs` - and the arm that returned a function for `prop === "login"` was the one place the proxy added a member, against its own header and the surface contract's "adds no member and removes none" (§ 3). It is gone from `ng-proxy.ts`; the note stays as the record of what the proxy must never do again.
- **Defect - the passthrough could not survive the real `ng` (FIXED `1.0.0-dev.7`).** It was `Reflect.get(ng, prop).bind(ng)`, and `@ng-org/web`'s `ng` is itself a Proxy whose `get` trap answers every key - `bind` included - with a path-carrying callable returning a Promise. So the published `ng` handed back a promise for all 88 members and a caller got `<member> is not a function`. Invisible because the library's own internals bypass this proxy and every fake in the suite is a plain object. Now `Reflect.apply(real, ng, args)`; the stand-in in `test/ng-proxy.test.ts` is shaped like the real proxy, which is what makes the test one.
- Disappears at migration (the whole module).
## 2. NURI internals — the unexported slice of `nuri.ts`, plus the minting point
@@ -264,7 +266,7 @@ export function inspectOutbox(): void;
## Appendix — full internal export inventory (for diffing)
Fully internal modules: `shared-wallet/access-log.ts` (`AccessOp`, `setAccessLog`, `enabled`, `activeIdentity`, `accessLogPrefix`, `logStage`, `shortNuri`, `logAccess`); `emulated-verifier/machinery.ts` (`MACHINERY_NS`, `isMachinerySubject`); `surface/ng-proxy.ts` (`makeNg`); `emulated-verifier/open-repo.ts` (`SyncState`, `setOpenTimeoutForTests`, `resetOpenedRepos`, `getSyncState`, `ensureRepoOpen`, `ensurePhysicalRepoOpen`, `ensureReposOpen`); `shared-wallet/outbox-log.ts` (`inspectOutbox`); `shared-wallet/physical.ts` (`physicalCreate`, `physicalQuery`, `physicalUpdate`); `emulated-verifier/reach.ts` (`declareInfrastructure`, `isInfrastructure`, `resetInfrastructure`, `mayReach`, `assertMayReach`, `mustNotAttempt`); `emulated-verifier/read-filter.ts` (`filterReadable`, `makeReadFilteredView`).
Fully internal modules: `shared-wallet/access-log.ts` (`AccessOp`, `setAccessLog`, `enabled`, `activeIdentity`, `accessLogPrefix`, `logStage`, `shortNuri`, `logAccess`); `emulated-verifier/machinery.ts` (`MACHINERY_NS`, `isMachinerySubject`); `surface/ng-proxy.ts` (`makeNg`, `wrappedNg`); `emulated-verifier/open-repo.ts` (`SyncState`, `setOpenTimeoutForTests`, `resetOpenedRepos`, `getSyncState`, `ensureRepoOpen`, `ensurePhysicalRepoOpen`, `ensureReposOpen`); `shared-wallet/outbox-log.ts` (`inspectOutbox`); `shared-wallet/physical.ts` (`physicalCreate`, `physicalQuery`, `physicalUpdate`); `emulated-verifier/reach.ts` (`declareInfrastructure`, `isInfrastructure`, `resetInfrastructure`, `mayReach`, `assertMayReach`, `mustNotAttempt`); `emulated-verifier/read-filter.ts` (`filterReadable`, `makeReadFilteredView`).
Internal slices of partially-published modules: `model/nuri.ts` (`targetOf`, `parseNuri`) and `emulated-verifier/caps.ts` (`mintCap`); `emulated-verifier/connect.ts` (`startConnect`); `subscribe.ts` (`subscribePhysicalDoc`); `shared-wallet/account-registry.ts` (`reservedAccount`, `resetRegistryCache`, `resolveAccount`, `ensureAccount`, `isOwnInbox`, `myInboxes`, `addLink`, `readLinks`).