feat(xmpp): natieve calls F3 — companion-kanaal-paring (deterministische afleiding §5.1) #1135

Merged
brenno merged 6 commits from feat/native-calls-f3-companion into main 2026-08-02 16:37:31 +00:00
Owner

De companion-kanaal-paring van fase F3 (docs/design/NATIVE_CALLS.md §5.1): een deterministische afleiding van OciDecks companion-MUC uit de gedeelde conferentie-URL. Zo vinden twee OciDeck-clients met dezelfde Jitsi-link elkaar in dezelfde companion-kamer — zonder centraal register (P1) — waar OciDecks stuurvlak (presenter-sync, ops, presence) apart van de Jitsi-conferentie loopt.

Wat

  • lib/xmpp/companion_room.dartcompanionRoomLocalpart(conferenceUrl) normaliseert de URL (host lowercase, effectieve poort behouden, efemere #config/query eraf, trailing slashes eraf) en hasht die eenrichting met SHA-256 achter een geversioneerde salt tot ocideck-<hash>. Deterministisch (zelfde link → zelfde kamer) en niet-omkeerbaar (de kamernaam onthult de conferentie niet aan wie de link niet heeft). companionRoomJid plakt de MUC-service erachter.
  • De test-dialoog vervangt het rauwe-kamer-veld door een conferentie-URL-veld: bij invullen leidt hij de companion-kamer af (conference.<domein>), joint die via XmppMuc, en toont de kamer-JID plus welke OciDeck-gebruikers aanwezig zijn — de eigenlijke §5.1-flow (afleiden → joinen → herkennen). Bewaart nog steeds niets.

Waarborgen

  • Reviews, beide GO: beveiligingsarchitect (de onvertrouwde conferentie-URL wordt tot hex geneutraliseerd vóór hij een JID raakt — geen injectie; de afleiding is aantoonbaar eenrichting en lekt de conferentie niet; de companion-join rijdt over de bestaande NetGuard-gepinde sessie, geen nieuwe egress) en kernwaardenbewaker (P1/geen centraal register — versterkt de soevereiniteit; privacy; "bewaart niets"; eerlijke veld-evolutie). Review-punten doorgevoerd: de poort zit nu in de kamer-identiteit (twee deployments op dezelfde host maar andere poort collapsen niet), een try/finally om de join, en comment-correcties.
  • Geen nieuwe egress/dependency: package:crypto (sha256) was al aanwezig; de join rijdt over de F2/F3-sessie. Secrets/SAST schoon.
  • Tests (12, puur): determinisme, normalisatie (fragment/query/trailing-slash/host-case/poort), eenrichting (geen substring), nodeprep-veilig, companionRoomJid. Plus de bijgewerkte dialoog-widget-tests (companion-kamer + occupants + join-fout).
  • Docs: SOURCE_MAP (companion_room + dialoog-entry), NATIVE_CALLS §5.1 van "open detail" naar "gebouwd". l10n: 2 nieuwe strings × 31 talen; de weessleutel van het oude kamer-veld opgeruimd.

Poortstand

Op verse origin/main gerebased. make check volledig groen — alle statische poorten, de volledige testsuite én de dekkingsvloeren. Secrets (gitleaks/trufflehog) en SAST (semgrep) schoon. Geen pubspec/SBOM-wijziging.

De companion-kanaal-paring van fase F3 (`docs/design/NATIVE_CALLS.md` §5.1): een **deterministische afleiding** van OciDecks companion-MUC uit de gedeelde conferentie-URL. Zo vinden twee OciDeck-clients met dezelfde Jitsi-link elkaar in dezelfde companion-kamer — **zonder centraal register** (P1) — waar OciDecks stuurvlak (presenter-sync, ops, presence) apart van de Jitsi-conferentie loopt. ## Wat - **`lib/xmpp/companion_room.dart`** — `companionRoomLocalpart(conferenceUrl)` normaliseert de URL (host lowercase, effectieve poort behouden, efemere `#config`/query eraf, trailing slashes eraf) en hasht die **eenrichting met SHA-256** achter een geversioneerde salt tot `ocideck-<hash>`. Deterministisch (zelfde link → zelfde kamer) en niet-omkeerbaar (de kamernaam onthult de conferentie niet aan wie de link niet heeft). `companionRoomJid` plakt de MUC-service erachter. - De **test-dialoog** vervangt het rauwe-kamer-veld door een **conferentie-URL-veld**: bij invullen leidt hij de companion-kamer af (`conference.<domein>`), joint die via `XmppMuc`, en toont de kamer-JID plus welke OciDeck-gebruikers aanwezig zijn — de eigenlijke §5.1-flow (afleiden → joinen → herkennen). Bewaart nog steeds niets. ## Waarborgen - **Reviews, beide GO**: beveiligingsarchitect (de onvertrouwde conferentie-URL wordt tot hex geneutraliseerd vóór hij een JID raakt — geen injectie; de afleiding is aantoonbaar eenrichting en lekt de conferentie niet; de companion-join rijdt over de bestaande NetGuard-gepinde sessie, geen nieuwe egress) en kernwaardenbewaker (P1/geen centraal register — versterkt de soevereiniteit; privacy; "bewaart niets"; eerlijke veld-evolutie). Review-punten doorgevoerd: de **poort** zit nu in de kamer-identiteit (twee deployments op dezelfde host maar andere poort collapsen niet), een **`try/finally`** om de join, en comment-correcties. - **Geen nieuwe egress/dependency**: `package:crypto` (sha256) was al aanwezig; de join rijdt over de F2/F3-sessie. Secrets/SAST schoon. - **Tests** (12, puur): determinisme, normalisatie (fragment/query/trailing-slash/host-case/poort), eenrichting (geen substring), nodeprep-veilig, `companionRoomJid`. Plus de bijgewerkte dialoog-widget-tests (companion-kamer + occupants + join-fout). - **Docs**: SOURCE_MAP (`companion_room` + dialoog-entry), NATIVE_CALLS §5.1 van "open detail" naar "gebouwd". l10n: 2 nieuwe strings × 31 talen; de weessleutel van het oude kamer-veld opgeruimd. ## Poortstand Op verse `origin/main` gerebased. **`make check` volledig groen** — alle statische poorten, de volledige testsuite én de dekkingsvloeren. Secrets (gitleaks/trufflehog) en SAST (semgrep) schoon. Geen pubspec/SBOM-wijziging.
De companion-MUC (waar OciDecks stuurvlak los van de Jitsi-kamer loopt,
§5.1) wordt zonder centraal register (P1) gevonden: companionRoomLocalpart
normaliseert de gedeelde conferentie-URL (host lowercase, efemere
#config/query eraf, trailing slashes eraf) en hasht die eenrichting met
SHA-256 achter een geversioneerde salt tot ocideck-<hash>. Twee clients
met dezelfde Jitsi-link rekenen dezelfde kamer uit; de kamernaam onthult
de conferentie niet (eenrichting), en de salt-versie laat het schema
mee-evolueren zonder stille divergentie. 10 tests (determinisme,
normalisatie, eenrichting, nodeprep-veilig).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Het kamer-veld wordt een conferentie-URL-veld: bij invullen leidt de
dialoog de companion-kamer af (companionRoomJid op conference.<domein>),
joint die, en toont de kamer-JID plus welke OciDeck-gebruikers aanwezig
zijn. Vervangt de rauwe-kamer-demo van de MUC-slice door de eigenlijke
§5.1-flow (afleiden → joinen → herkennen). Bewaart nog steeds niets.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Beveiligingsarchitect + bewaker:
- Normalisatie neemt nu de (effectieve) poort mee: twee Jitsi-deployments
  op dezelfde host maar verschillende poort collapsen niet meer naar één
  companion-kamer; een expliciete default-poort matcht de impliciete.
  Twee tests dekken dit.
- try/finally om de companion-join in de dialoog: leave()+close() lopen
  altijd, ook als XmppMuc.join() ooit zou gooien (defensief).
- Comment-correcties: 'rev the salt version' (niet de vaste prefix); de
  onjuiste §7.1.6-verwijzing verwijderd.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Twee nieuwe bronstrings uit xmpp_test_connection_dialog.dart:
- 'Conferentie-URL (optioneel): toont de OciDeck-companion-kamer'
- 'Companion-kamer'

'companion' blijft als benoemde feature-term staan (NATIVE_CALLS.md §5.1,
zoals de Nederlandse bron zelf); kamer/conferentie/optioneel/toont zijn per
taal vertaald met de bestaande terminologie.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
l10n(xmpp): F3 — ruim de weessleutel van het oude kamer-veld op
Some checks failed
scans / scans (pull_request) Has been cancelled
static-gate / static-gate (pull_request) Has been cancelled
8a5409ee13
De MUC-slice-string 'Kamer testen (optioneel): kamer@service' is uit de
code verdwenen (vervangen door het conferentie-URL-veld); verwijder zijn
nu-ongebruikte vertalingen uit alle 31 talen (bewaker-bevinding).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
brenno merged commit 2b0414889a into main 2026-08-02 16:37:31 +00:00
Sign in to join this conversation.
No description provided.