feat!: la famille ORM est publiee enveloppee, et le ng publie cesse de rendre des promesses
This commit is contained in:
@@ -48,4 +48,5 @@ The polyfill's published surface has drifted from the SDK's: invented names, inv
|
||||
- T01.c - `useShapeQuery` takes the SDK's `Scope`, re-exported as a passthrough. Our three literals became `StoreType`, internal only: VERIFIED they are upstream's own `store_type`, so only the NAME was invented. A store is now named by its REFERENCE (`privateStore()` / `protectedStore()` / `publicStore()`), and `createEntityDoc(store?)` takes one, private when omitted, as `doc_create` does. `listMyEntityDocs`, `resolveScopeGraph` and `resolveWriteGraph` unpublished, still internal - T01.d removes the read path's last caller. VERIFIED: public and protected share one store id here, so the reference must be the index document. `1.0.0-dev.5`.
|
||||
- Package refresh (2026-09-21) - `@ng-org/*` moved to web alpha.14 / orm alpha.21 / shex-orm alpha.9 / alien-deepsignals alpha.13. The live ORM read now STARTS against the deployed broker: `6 passed, 0 failed, 6 declared`, ready in 16ms, delete reached the document. `bug_useshape-live-read-needs-a-newer-broker` DELETED - the deployment was never behind, our packages were. T01.d's blocker LIFTS. Also surfaced: `OrmSubscription` is now `RdfOrmSubscription` (T01.e's proposal names the old one); `Scope.graphs` is REQUIRED and its `[]` means the EMPTY set while `subjects: []` means NO filtering - the two axes read `[]` in opposite directions, which T01.d must not get wrong; six e2e files imported `ng-e2e-helpers` without the polyfill declaring it, fixed as `workspace:*`.
|
||||
- T01.d - `useShapeQuery` reads through `RdfOrmSubscription.getOrCreate`, injected as `configure({ ormSubscription })`; absent, the read publishes `isError` naming it. Scope resolution, the `ensureReposOpen` barrier, `readUnion` and the `@type` filter are gone from that path; `graphs`/`subjects`/`did:ng:i` reach the engine verbatim. The observable, snapshot, state and capability filter stay ours. `isError` KEPT, wired to the one real failure (the query refusing to open). A start the ENGINE refuses is swallowed upstream, so it reads `isPending` for ever - recorded in code and contract, no timeout invented. `userStoreDoc` and `liveStartWithConfig` deleted. VERIFIED: `listMyEntityDocs` is NOT dead, its own suite and an e2e journey call it. The change silently broke `examples/notebook/`, repaired out of boundary and deliberately. `1.0.0-dev.6`, major, 42/42 e2e.
|
||||
- T01.e - `getObjects` and `insertObject` published WRAPPED at upstream's names, parameters and returns. Read is capability-filtered per `@graph`; the write takes `assertMayReach` + `assertMayWrite` BEFORE the call, and `graph_orm_update` now carries the same ownership guard, so the ORM rights hole is closed. NOT published, each with a checkable reason: `RdfOrmSubscription` (pooled with no identity in the key), `DiscreteOrmSubscription`, `ngSession`, `getRaw`, `watch`/`effect`, `removeObject` (in alpha.21 but absent from the pinned `nextgraph-rs`, so no citation resolves). `1.0.0-dev.7`, MAJOR. ROOT CAUSE FOUND for the consumer's `orm_start_graph is not a function`: `makeNg()`'s passthrough did `.bind(ng)`, and the SDK's `ng` is an async proxy whose `get` trap answers EVERY key including `bind` with a path-carrying callable - so the published `ng` returned a PROMISE for all 88 members. Now `Reflect.apply`, pinned by `test/ng-proxy.test.ts`. The e2e only proves it since `initNg` routes the ORM through the wrapper - before, `polyfill-entry.ts` handed `initNg` the raw SDK object, which is why the suite stayed green while the documented path was dead.
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
id: T01.e
|
||||
title: Publish the ORM family with the rights filter
|
||||
parent: T01
|
||||
depends_on: [T01.b, T01.d]
|
||||
created: 2026-09-16
|
||||
claimed_by: null
|
||||
claimed_at: null
|
||||
blocked: false
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Wrap and publish the ORM family this package does not expose: `getObjects` and `insertObject` at **identical signatures**, with the rights filter; deletion in whatever shape T01.b established; and whatever T01.b's arbitration settled for `OrmSubscription`, `DiscreteOrmSubscription` and `ngSession`.
|
||||
|
||||
**Why the dependencies.** On **T01.b**: the deletion shape and the three arbitrations are established there — read its `## Result` and the `knowledge_` leaf it names, rather than re-reading `nextgraph-rs`. On **T01.d**: both children change the published surface and edit the same contract, and they must not run concurrently.
|
||||
|
||||
**The problem is a rights hole, not a missing convenience.** Today an application has to import these straight from `@ng-org/orm`, and then receives **every identity's data** out of the shared wallet with **nothing signalling it**. The filter that closes it is `makeReadFilteredView` (`packages/polyfill/src/emulated-verifier/read-filter.ts`, annotated `kind=aligned level=1 ref=engine/verifier/src/verifier.rs:load_repo_from_read_cap`): it keeps only items whose document — their `@graph` — the current holder has a cap for, applied per document on what comes back. That is the emulation of what the broker will bound at delivery, done where the target does it. `packages/polyfill/src/surface/use-shape.ts` is the existing example of a passthrough that filters results.
|
||||
|
||||
**Identical signature means passed through, not translated.** If a parameter cannot be passed through, stop and say what would have to be built beneath it — that is the real decision, and it is being made by the parameter (`.project/rules/nextgraph/surface-mirrors-the-sdk.md`). Do not invent an ergonomic wrapper that an application would have to unlearn.
|
||||
|
||||
**Open questions to carry or close — do not invent past them:**
|
||||
|
||||
- If T01.b left the **deletion** shape unestablished, this child does **not** specify one. Report it and publish the rest.
|
||||
- **A write path cannot be rights-filtered the way a read is.** The filter is a read emulation. `packages/polyfill/src/surface/ng-proxy.ts` already overrides `sparql_update` with an emulated write guard — read it before deciding what `insertObject` does with an unauthorized write. Do not invent a write guard the target does not have; if the answer is "the existing guard covers it", say which line does.
|
||||
- If T01.b's arbitration for `OrmSubscription` / `DiscreteOrmSubscription` / `ngSession` is a proposal the user has not confirmed, and acting on it would **remove or rename** something, stop and ask. Adding is reversible; removing a published symbol is a major that a caller pays for.
|
||||
|
||||
**This child owns the contract edit and the version bump for its own change.** Edit `.project/concepts/app-contract/polyfill-surface/contract_polyfill-surface.md` — `## Surface`, `## Guarantees` (what the filter promises about what comes back), `## Non-guarantees`, `## Change policy`. By the contract's own rules, symbols added with nothing existing moved is a **minor**; if the arbitration removes or narrows anything it is a **major**. Apply the rule, do not assume a level. No other child edits the contract for this change.
|
||||
|
||||
**Also in scope:** `packages/polyfill/src/index.ts` (the export and its `@provenance` lines — each new symbol needs one, in the form T01.a installed), `test/vocabulary.test.ts` and `test/app-surface.test.ts` (they pin the export inventory), `test/provenance.test.ts` coverage, `docs/api-contract.md`, `packages/polyfill/README.md`, `packages/polyfill/docs/polyfill-reference.md`. New behaviour needs new tests, including the rights case: a second identity's data must not come back.
|
||||
|
||||
**Hard gate:** `bun test` → 0 fail; `bunx tsc --noEmit -p packages/polyfill/tsconfig.json` → exit 0; `bunx tsc --noEmit -p packages/polyfill/e2e/tsconfig.json` → exit 0; `python3 ~/.claude/skills/concept/lint.py` → 0 ERROR. Anti-cheat: no `any`, no `@ts-ignore`, no deleting or skipping a test, no widening an assertion.
|
||||
|
||||
**Resolved since planning (2026-09-16).** A write is not rights-filtered like a read: upstream bounds a write by write capability, not by hiding results. So `insertObject` gets a GUARD BEFORE the write, following the package's existing pattern (`assertOwnInbox`, `mustNotAttempt`, `assertMayReach`) — never a filter over what it returns.
|
||||
|
||||
**Resolved since planning (2026-09-21), and it overturns T01.b's proposal.** NO SDK element is published as-is, ever. Re-exporting one hands the caller a path straight to the SDK that SHORT-CIRCUITS this package's emulation - the capability filter, and above all the shared-wallet identity boundary. T01.b proposed publishing `OrmSubscription` unchanged; that proposal is void. Every symbol this package offers from the ORM family is WRAPPED, at the same name and signature, with the emulation applied. If a symbol cannot be wrapped meaningfully, it is not published at all - that is a valid outcome, not a failure.
|
||||
|
||||
Note also: `OrmSubscription` was renamed `RdfOrmSubscription` in `@ng-org/orm@0.1.2-alpha.21`, and `getOrCreate` returns a narrowed `RdfOrmSubscriptionFor<...>` rather than the class. T01.b's proposal named the old symbol.
|
||||
|
||||
## Progress
|
||||
|
||||
## Result
|
||||
Reference in New Issue
Block a user