2026 03 17_matrix_core_adoption_plan - mark-ik/graphshell GitHub Wiki
Date: 2026-03-17
Status: Active / planning
Scope: Execution plan for introducing MatrixCore as Graphshell's durable
shared-space substrate without collapsing existing iroh, Verse, or Nostr boundaries.
Parent: 2026-03-17_matrix_layer_positioning.md
Related docs:
-
register/matrix_core_registry_spec.md -
MatrixCorecapability-provider boundary - register/2026-03-17_matrix_core_type_sketch.md - Rust-facing registry, worker, and normalized-event type sketch
- 2026-03-17_multi_identity_binding_rules.md - three-identity model and binding rules
- 2026-03-17_matrix_event_schema.md - Graphshell-owned Matrix room event families and routing rules
- 2026-03-05_network_architecture.md - current network layer assignments
- register/2026-03-08_sector_c_identity_verse_plan.md - current identity/user-signing lane and binding seam
- register/SYSTEM_REGISTER.md - Register routing, control-panel, and capability boundary rules
Add a Matrix-backed collaboration lane for:
- durable shared graph rooms
- room-backed message history
- membership and moderation semantics
- private/team collaboration spaces
- optional bridge affordances to Nostr publication surfaces
while preserving the existing role split:
-
iroh= trusted peer/session transport - Verse /
libp2p= subject/community transport and replication -
Nostr= public/social identity and relay-native publication -
Matrix= durable room/state substrate
This plan does not authorize:
- replacing
irohfor Device Sync or Coop transport - replacing Verse as the canonical subject/community substrate
- replacing Nostr as the portable public/social identity layer
- exposing raw homeserver connections, tokens, or crypto material to mods
- treating Matrix room history as reducer-owned graph truth
The lane should land in four layers:
-
Register layer:
MatrixCorenative provider boundary, capability IDs, diagnostics, and worker ownership -
Identity layer: explicit Matrix ID binding into the existing
NodeId/UserIdentitymodel without key reuse - Projection layer: normalize room events into Graphshell-owned typed projections
- Surface layer: room/workspace UI, membership views, and graph-space affordances
The reducer remains the sole owner of graph truth. Matrix is an external collaboration substrate that can propose state changes through bounded carriers.
Matrix room events are divided into three buckets:
These update Graphshell-owned room/session state but never propose graph mutation:
- room timeline messages
- membership changes
- typing/read-receipt/presence-like metadata
- moderation and role metadata
These may create or refresh Graphshell projections, but only through explicit host-owned projection code:
- room/topic metadata
- room avatar/name metadata
- pinned/reference events that map to graph-space descriptors
- explicit Graphshell room-state events under a Graphshell namespace
Only explicitly allowlisted Graphshell-owned event types may propose graph/workbench intents.
Initial allowlist:
graphshell.room.link_nodegraphshell.room.open_workspace_refgraphshell.room.attach_referencegraphshell.room.publish_selection
Everything else is observe-only until separately specified.
Guardrail:
- No generic "arbitrary Matrix event -> GraphIntent" adapter is allowed.
Create the provider boundary and supervised worker shape without yet committing to full room UX.
Deliver:
-
MatrixCoreRegistrystruct/API scaffold -
RegistryRuntimewiring -
ControlPanelworker supervision entry point for Matrix sync/session workers - diagnostics channel registration
- settings-visible session status placeholder
Done gates:
-
MatrixCoreRegistryexists as a real runtime-owned type - capability IDs from matrix_core_registry_spec.md are wired into manifest/spec surfaces
-
ControlPanelcan supervise a no-op or stub Matrix session worker - diagnostics channels emit for startup, shutdown, and capability denial
Land authenticated homeserver session handling while preserving the host-owned secret boundary.
Deliver:
- session open/close flow
- device/session persistence policy
- token/key storage strategy
- sign-in/sign-out state transitions
- failure and degraded-mode diagnostics
Done gates:
- no raw Matrix session tokens or crypto material are exposed to mods or page-local code
- session lifecycle is host-owned and survives restart according to documented policy
- login failure, session expiry, and logout paths emit explicit diagnostics
- settings surface can show current homeserver/account/session state
Add durable room synchronization and a Graphshell-owned projection model for room state.
Deliver:
- room subscription/sync worker
- room membership snapshot model
- room metadata projection
- timeline projection storage boundary
Done gates:
-
room_subscribe/room_unsubscribe/room_membershippaths exist behind capability gates - room sync is supervised by
ControlPanel, not ad hoc background tasks - membership state is queryable without leaking Matrix SDK internals across the app
- room metadata and membership projections survive restart as designed
Define the event normalization contract and the first bounded set of room events that may propose graph/workbench changes.
Deliver:
- normalized Matrix event enum or equivalent projection layer
- Graphshell namespaced event types for graph-space interaction
- reducer/workbench bridge mapping for the initial allowlist
- rejection diagnostics for unsupported or malformed event types
Done gates:
- observe-only vs projectable vs intent-capable event classes are encoded in one authority doc/code seam
- only allowlisted Graphshell-owned event types may produce intent proposals
- rejected room events emit diagnostics rather than silently no-op
- no direct graph mutation occurs from Matrix callbacks/workers
Extend the existing identity lane so Matrix IDs can be linked to NodeId and npub
without collapsing the model.
Deliver:
- binding record authority/store
- Matrix ID link flow
- verification-state presentation
- revocation/unlink path
Done gates:
- Matrix ID bindings follow 2026-03-17_multi_identity_binding_rules.md
- strong and weak verification states are distinguished in UI/runtime policy
- unlinking a Matrix account does not damage the underlying
NodeIdornpub - permission/membership state is not silently transferred across ecosystems
Expose Matrix-backed rooms as first-class Graphshell surfaces.
Deliver:
- room list / join / leave flow
- room detail surface
- membership/moderation panels
- room-to-graph-space affordances
Done gates:
- users can enter a room-backed surface without needing direct reducer knowledge
- membership and role semantics are visible in the surface
- room-scoped graph affordances use bounded actions, not hidden side effects
- diagnostics/empty/degraded states are represented in UI
Add explicit, opt-in bridge actions between Matrix rooms and Nostr publication lanes.
Deliver:
- publish-to-Nostr actions for selected room content
- linked-identity display in room/member surfaces
- bridge-policy prompts and diagnostics
Done gates:
- bridge actions are explicit and user-initiated
- Nostr publication still routes through
NostrCoreRegistry - Matrix moderation state is not treated as Nostr relay policy
- unverified identity links cannot silently authorize bridge actions
All async Matrix activity remains outside the reducer:
- session sync workers run under
ControlPanel - workers emit normalized events, diagnostics, and bounded intent proposals
- reducer/workbench authorities remain synchronous and deterministic
Preferred routing pattern:
Matrix homeserver/client
-> MatrixCore worker
-> normalized room event
-> (a) projection state update
-> (b) optional allowlisted intent proposal
-> reducer/workbench authority
Anti-patterns to forbid:
- Matrix callbacks mutating graph state directly
- raw SDK client handles escaping into arbitrary UI code
- generic "room event executes command" paths without allowlisting
The adoption lane must keep these storage scopes distinct:
-
device-local: Matrix session/device state, local
NodeId, local secret material - workspace-local: room selections, presentation state, projection caches where appropriate
- room-derived: synchronized room metadata and timeline-derived projections
-
public/social: Nostr publications and linked
npubmetadata
No room-derived data should be mistaken for canonical graph truth unless explicitly imported through reducer-owned paths.
Mitigation:
- keep Matrix room state external
- import/project selectively
- require explicit graph-owned event types for mutation proposals
Mitigation:
- keep the three-identity model explicit
- show verification state everywhere identities are linked
- require explicit user linking and unlinking flows
Mitigation:
- keep non-goals active in this plan and in
matrix_core_registry_spec.md - require architecture review before any Matrix lane claims transport or community authority
-
M1runtime skeleton with diagnostics only -
M2session lifecycle and settings surface -
M3room sync + membership projection -
M5identity binding authority -
M4allowlisted graph-event projection -
M6room surfaces -
M7optional Nostr bridge actions
Reason:
- the session and projection seams need to exist before graph-affecting room events are safe
- identity binding should land before rich room/member UI claims cross-ecosystem coherence
- Nostr bridging should stay last so it builds on stable room and identity semantics
This lane is credible when all of the following are true:
- Graphshell can maintain a host-owned Matrix session without leaking secrets
- room membership and metadata are projected into stable Graphshell surfaces
- only allowlisted Graphshell-owned room events can propose graph/workbench actions
- Matrix IDs,
npub, andNodeIdremain distinct but linkable through explicit verified bindings - Matrix augments the stack as the durable room layer without displacing
iroh, Verse, or Nostr