docs: readUnion énumère par contrainte d'émulation, pas par manque de la cible

This commit is contained in:
Sylvain Duchesne
2026-09-15 15:31:07 +02:00
parent e5d73a670b
commit 88ce8d17c5
+23 -4
View File
@@ -170,12 +170,31 @@ async function readDoc(
* isolation needs a repo per entity), but it is a recommendation about writing: the * isolation needs a repo per entity), but it is a recommendation about writing: the
* read reports what is there. * read reports what is there.
* *
* Never an anchorless union-scan over all graphs (which is O(wallet size) and wrong * ── Why this enumerates, and why that is OURS and not the target's ────────
* on a shared / bloated wallet — the footgun this path exists to avoid). Each doc is * Upstream DOES have a query that spans many documents: `resolve_target_for_sparql`
* read with an anchored default-graph query, O(1) per doc, independent of wallet * (`engine/verifier/src/request_processor.rs`) accepts `UserSite` — or no target at
* size — a non-empty wallet no longer matters. Reads run in parallel via `Promise.all`. * all — and returns `Ok(None)`, which the verifier itself annotates "QUERYING UNION
* GRAPH". It is refused for updates (`InvalidTarget`) and allowed for reads. So
* "the target cannot read several documents at once" is FALSE, and this path must
* not be read as compensating for a missing upstream capability.
*
* What makes that union unusable HERE is our own emulation: one shared wallet holds
* EVERY virtual identity, so a scan over all graphs crosses identity boundaries that
* upstream does not have (there, a wallet is one person's). The cost argument —
* O(wallet size) — follows from the same artefact. Both reasons are `polyfill-era`.
*
* Each doc is therefore read with an anchored default-graph query, O(1) per doc,
* in parallel via `Promise.all`.
*
* OPEN, and deliberately not settled here: whether enumerating is what an
* application should be taught at all. Targeting `PrivateStore` is a first-class
* option upstream, and whether it reaches a document's CONTENTS — or only the store
* repo's own graph, documents being repos of their own — decides it. Until that is
* established, treat this shape as unconfirmed rather than as the aligned answer.
*/ */
// @provenance readUnion kind=aligned level=2 ref=sdk/js/lib-wasm/src/lib.rs:sparql_query — one anchored query per document — upstream's own anchoring (`resolve_target_for_sparql`), composed client-side // @provenance readUnion kind=aligned level=2 ref=sdk/js/lib-wasm/src/lib.rs:sparql_query — one anchored query per document — upstream's own anchoring (`resolve_target_for_sparql`), composed client-side
// @provenance readUnion.enumeration kind=invention level=none ref=none — upstream offers a union query over many documents (`UserSite`/no target → union graph); enumerating instead is OURS, forced by the shared wallet, and UNCONFIRMED as the shape to teach — see the docstring's open question
// @provenance readUnion.swallow kind=invention level=none ref=none — a failing document is skipped and reads as empty; upstream has no batch read at all, so it has no counterpart for what a partial failure should do
export async function readUnion( export async function readUnion(
docsLike: NuriLike[], docsLike: NuriLike[],
onUnreadable?: (doc: Nuri, error: unknown) => void, onUnreadable?: (doc: Nuri, error: unknown) => void,