Skip to content

[feat] roadmap 13 batch M1 - open-core extension points (inert seams) - #38

Merged
AlexZ005 merged 2 commits into
mainfrom
feature/roadmap-13-open-core-m1
Jul 23, 2026
Merged

[feat] roadmap 13 batch M1 - open-core extension points (inert seams)#38
AlexZ005 merged 2 commits into
mainfrom
feature/roadmap-13-open-core-m1

Conversation

@AlexZ005

Copy link
Copy Markdown
Collaborator

Roadmap #13 Batch M1 — open-core extension points. The prerequisite for the closed cloud product (M2): the seams a cloud plugin plugs into, so registration / rooms / roles live outside this MIT repo. With no plugin configured, every seam is inert — the OSS build behaves byte-for-byte as before.

Seams

  • Capability gate (cloudHooks.canApply) — one receive-side choke point at the top of conn.on('data') (peerHandler.svelte.js). Default allows everything; a plugin's provider drops a sender's disallowed message types (the receive-side layer roles enforcement needs). A small ALWAYS_ALLOWED floor (hosts / userdata / locked / the get* late-join requests) can't be gated, so a plugin can never brick the mesh; a throwing provider is treated as allow.
  • Auth hook (authorize(peerId)) — in handleConnection, lets a provider pre-approve known/authenticated peers, skipping the manual Approve. Default keeps the whitelist + approval flow byte-identical.
  • Plugin loader (cloudPlugin.js) — boot-time dynamic import() of a plugin URL from VITE_CLOUD_PLUGIN (prod) or localStorage.cloudPluginUrl (dev). Hands it a small cloudApi. Load/throw is caught + toasted; dynamic import only (bundle + module-cycle rules).
  • UI mount pointsmountConnect / mountUsersSection render a plugin mount fn (el) => cleanup via CloudSlot.svelte, decoupled from the app's framework version. appNotice (the first-run banner) is the shared-state seam.

Included

  • static/cloud-plugin-example.js — a dependency-free reference plugin (also the e2e fixture) exercising every seam.
  • OPEN-CORE.md — the plugin contract + author rules.
  • tests/e2e/open-core-m1.test.cjs — default path fully inert; the example plugin drives the gate/auth/mounts/banner; unloading restores defaults. All checks PASS.

Verification

  • svelte-check 499/77 (baseline held) · npm run build green.
  • Default-path inertness proven single-page (canApply is unconditionally true with no provider, so the gate early-return never fires). The two-peer replication regression is environment-gated locally (the theprototype.app hosts mapping is currently disabled), not a code concern.

Notes

  • tests/e2e/connect-overlay.test.cjs is a pre-existing stale test (queries .p-8, obsoleted by the roadmap Feature/properties #9 Connect rewrite) — untouched here.
  • Next: M2 in the private theprototype.app-cloud repo — PocketBase (GitHub+Google OAuth, users/rooms/roles collections) + the client plugin (login, Browse Rooms, viewer/editor/admin with auto-promote).

🤖 Generated with Claude Code

Add the seams a closed "cloud" plugin plugs into, so registration/rooms/roles can
live OUTSIDE this MIT repo. With no plugin configured every seam is INERT - the OSS
build behaves byte-for-byte as before.

- cloudHooks.js (store-only, no cycles): capability gate canApply(peerId, msgType)
  with a pluggable provider (default allow-all) + an ALWAYS_ALLOWED floor of
  connection/handshake types so a plugin can never brick the mesh; an auth provider
  (authorize) accessor; connectSlot / usersSlot UI mount stores.
- peerHandler: ONE receive-side choke point at the top of conn.on('data')
  (drop when !canApply); an auth hook in handleConnection that lets a provider
  pre-approve known peers (default keeps the whitelist + approval flow).
- cloudPlugin.js: boot-time dynamic import of a plugin URL (VITE_CLOUD_PLUGIN or the
  localStorage cloudPluginUrl dev override); hands it a small cloudApi
  (setCapabilityProvider/setAuthProvider, appNotice, getPeers, mountConnect/
  mountUsersSection, toast). Failure is caught + toasted; dynamic import only.
- CloudSlot.svelte: renders a plugin mount fn (el)=>cleanup into a DOM node, so a
  separately-built plugin owns its own rendering. Mounted in Connect (login/browse)
  and the Users popover (roles).
- static/cloud-plugin-example.js: dependency-free reference plugin (also the e2e
  fixture) exercising every seam.
- OPEN-CORE.md: the plugin contract + rules.
- e2e open-core-m1: default path fully inert; the example plugin drives the gate,
  auth, mount points and banner; unloading restores defaults.

svelte-check 499/77, build green. Two-peer replication regression is environment-
gated (hosts mapping for theprototype.app is disabled locally); default-path
inertness is proven single-page (canApply is unconditionally true with no provider).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@AlexZ005
AlexZ005 merged commit 47256c3 into main Jul 23, 2026
A cloud plugin is a separate build with no access to the engine's stores, so it
needs its OWN way to replicate state across the mesh (roles map, room announces).
Add it to the cloudApi:
- sendCloud(payload) broadcasts { type:'cloud', payload } to peers.
- onCloudMessage(fn) receives them; core routes {type:'cloud'} in conn.on('data')
  to cloudHooks.dispatchCloudMessage.
- 'cloud' joins the ALWAYS_ALLOWED floor so a plugin's own capability gate can
  never drop its control channel.
Example plugin + OPEN-CORE.md + e2e updated (receives a dispatched cloud message).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@AlexZ005
AlexZ005 deleted the feature/roadmap-13-open-core-m1 branch August 5, 2026 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant