Repository navigation
docs: WASM-CONSUMER-GUIDE — der Browser ist ein Consumer wie jeder andere - #270
Conversation
…ndere Der Browser sieht wie eine neue Schicht aus und ist keine. Er ist ein Consumer, gebunden an dieselbe Invariante: die classid ist reine Adresse, die Magie liegt an ihrem Aufloesungsziel. Was am wasm-Rand wirklich anders ist, ist schmal -- wie Bytes hineinkommen, was den Link ueberlebt, und wo Arithmetik ihre Vektorregister herbekommt. Das Dokument sind diese drei Dinge und sonst nichts, damit eine Browser-Session den Kanon weder neu herleitet noch neu implementiert. Der P0-Pin leistet hier echte Arbeit: "der Schluessel prerendert Knoten mit null Value-Decode" ist fuer einen Browser-Consumer keine Optimierung, sondern die ganze Architektur. Ein Client kann ein Feld legen und zeichnen, ohne einen einzigen Wert dekodiert zu haben; die Wert-Haelfte darf spaeter, teilweise oder nie ankommen. Das macht eine Browser-Schicht ueber einem Netz ueberhaupt erst tragfaehig. Die Consumer-Falle hat eine browser-foermige Variante, die benannt gehoert: der FFI-Rand ist keine Lizenz fuer eine lokale Kopie des Kanons. Ein nach JS gespiegeltes Codebook ist dieselbe Verletzung wie eine *_CODEBOOK-Kopie serverseitig, nur mit schlimmerem Radius -- es driftet jetzt pro Browser-Tab. Firewall am wasm-Rand: kein JSON auf diesem Pfad (das ABI IST das Wire-Format; ein Consumer, der JSON empfaengt und Objekte baut, hat genau die Serialisierung wieder eingefuehrt, die ADR-022/023 entfernt -- und dazu ein Objekt pro Knoten allokiert). Bytes einmal am Mount-Rand besitzen, danach nur noch borgen. Die wasm-spezifische Falle: der Link ist ein Filter. Gemessen in a2ui-rs -- vor den Exporten 1.269.153 B, 2 SIMD-Instruktionen, NULL Layout-Symbole; danach 4.880.319 B, 13.375, 121. Das Crate kompilierte, linkte und lieferte nichts aus. crate-type = cdylib ist noetig und nicht hinreichend. Und zwei Regeln zur Beweisfuehrung, beide aus eigenem Fehler: mit UND ohne Target-Feature bauen, weil die Null die andere Zahl erst bedeutend macht; und Widerspruechen nachgehen statt Erklaerungen. Der schlechte Beleg oben wurde nicht durch Nachlesen gefunden, sondern weil 2 Instruktionen im Modul nicht zu 801 im Archiv passten -- und dieser Gap fuehrte zum eigentlichen Defekt. Eine schlampige Zahl kostet mehr als ihre eigene Ungenauigkeit: sie kostet die Anomalie, die sie sonst aufgedeckt haette. Companions: ndarray .claude/knowledge/wasm-simd-consumer-guide.md (Polyfill-Haelfte), a2ui-rs docs/WASM-INTEGRATION.md (Rezept-Haelfte). Append-only, Status GUIDE v1.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_6db022ed-74ea-46fc-90ff-faf236e89816) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ebc304fd14
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Everything in `OGAR-CONSUMER-BEST-PRACTICES.md`. A wasm consumer pulls a | ||
| classid the same way, composes a render address the same way, authorizes | ||
| the same way, and is subject to the same anti-pattern catalogue. |
There was a problem hiding this comment.
Keep RBAC enforcement before the browser wire
When a surface contains role-restricted fields, saying that the wasm consumer “authorizes the same way” makes client-side authorization sound sufficient. The existing A2UI contract instead requires WideFieldMask ∩ role-mask on the server so unauthorized fields are absent from the wire (docs/A2UI-SCREEN-ADDRESSING-PROPOSAL.md:60-64, also crates/ogar-a2ui-frame/src/lib.rs:31-34); anything delivered to browser wasm remains observable even if the renderer hides it. Qualify that classid semantics remain unchanged while authoritative authorization and projection must happen in the server/session tier before transmission.
Useful? React with 👍 / 👎.
| 2. **Own the bytes once, borrow forever after.** Take owned bytes at the | ||
| mount boundary and let every read borrow into that one buffer. A | ||
| borrowed slice across the FFI ties the client's lifetime to a buffer JS | ||
| is free to release; a per-frame copy re-pays the cost the zero-copy view | ||
| exists to avoid. One copy when the stream arrives, none thereafter. |
There was a problem hiding this comment.
Account for every chunk in the live frame stream
For a long-lived addressed surface, new NodeDelta frames arrive after mount, so one initial allocation cannot own bytes that have not arrived yet. The documented protocol is explicitly a flat frame stream (docs/A2UI-SCREEN-ADDRESSING-PROPOSAL.md:117-121), and the in-repo decoder currently materializes each delta's mask and values (crates/ogar-a2ui-frame/src/lib.rs:247-255); following “borrow forever” literally therefore either retains an ever-growing stream or prevents later updates. State the invariant per received chunk or prescribe a reusable wasm-owned ring/buffer, while retaining the intended prohibition on per-render copies.
Useful? React with 👍 / 👎.
docs/WASM-CONSUMER-GUIDE.md— die Substrat-Hälfte. Companions: ndarray.claude/knowledge/wasm-simd-consumer-guide.md(Polyfill), a2ui-rsdocs/WASM-INTEGRATION.md(Rezept).Die These
Der Browser sieht wie eine neue Schicht aus und ist keine. Er ist ein Consumer, gebunden an dieselbe Invariante — die classid ist reine Adresse, die Magie liegt an ihrem Auflösungsziel. Was am wasm-Rand wirklich anders ist, ist schmal: wie Bytes hineinkommen, was den Link überlebt, wo Arithmetik ihre Vektorregister herbekommt. Das Dokument sind diese drei Dinge und sonst nichts, damit eine Browser-Session den Kanon weder neu herleitet noch neu implementiert.
§1 — der P0-Pin leistet hier echte Arbeit
„Der Schlüssel prerendert Knoten mit null Value-Decode" ist für einen Browser-Consumer keine Optimierung, sondern die ganze Architektur:
classid→ Template, HEEL/HIP/TWIG → Kaskadenposition (also bereits eine räumliche Anordnung), family+identity → Nachbarschaft.Ein Client kann ein Feld legen und zeichnen, ohne einen einzigen Wert dekodiert zu haben. Die Wert-Hälfte darf später, teilweise oder nie ankommen, und die Fläche bleibt kohärent. Das macht eine Browser-Schicht über einem Netz überhaupt erst tragfähig — ein serverseitiger Consumer muss darüber nie nachdenken.
Das Korollar ist eine Disziplin: ein wasm-Consumer färbt nach dem Byte und interpretiert es nie.
domain/vocabsind opake Palette-Indizes.§0 — die browser-förmige Variante der Consumer-Falle
Der FFI-Rand ist keine Lizenz für eine lokale Kopie des Kanons. Ein nach JS gespiegeltes Codebook „damit der Client nicht fragen muss" ist dieselbe Verletzung wie eine
*_CODEBOOK-Kopie serverseitig — mit schlimmerem Radius, weil es jetzt pro Browser-Tab driftet.§2 — Firewall am wasm-Rand
Kein JSON auf diesem Pfad. Das ABI ist das Wire-Format; ein Consumer, der JSON empfängt und Objekte baut, hat genau die Serialisierung wieder eingeführt, die ADR-022/023 entfernt — und dazu ein Objekt pro Knoten allokiert, was ein großes Feld nicht langsam, sondern unmöglich macht.
Bytes einmal am Mount-Rand besitzen, danach nur borgen. Ein geborgter Slice über die FFI bindet den Client an einen Buffer, den JS freigeben darf; eine Kopie pro Frame zahlt genau die Kosten, die der Zero-Copy-View vermeidet.
§3 — die wasm-spezifische Falle: der Link ist ein Filter
Gemessen 2026-08-14 in a2ui-rs, release:
Das Crate kompilierte, linkte und lieferte nichts aus.
crate-type = ["cdylib", "rlib"]ist nötig und nicht hinreichend. Ein schrumpfendes Modul nach dem Hinzufügen eines Subsystems ist derselbe Hinweis.§5 — zwei Regeln zur Beweisführung, beide aus eigenem Fehler
§4 — zwei Punkte, die kanon-förmig sind statt build-förmig
§6 — Definition of Done für einen Browser-Consumer
Sechs Punkte, jeder auf seinen Abschnitt zurückgebunden; der letzte lautet: benennt, was es NICHT gemessen hat.
Append-only, Status GUIDE v1. Nur Doku, kein Code.
Generated by Claude Code