2026 02 14_graph_tile_parity_research - mark-ik/graphshell GitHub Wiki
This document is research and analysis, not an adopted architecture decision. It captures skeptical critique of recent design discussions around graph/tile parity and proposes implications to evaluate. Treat this as input for design review, not as normative spec.
Question: Should Graphshell enforce parity between graph structure and tile-tree structure?
Short answer from this analysis: enforce semantic parity, avoid structural parity.
A strict 1:1 mapping between graph clusters/edges and pane/tab arrangement looks clean in theory, but creates fragile coupling in practice.
- Graph structure carries browsing semantics (identity, navigation provenance, grouping intent).
- Tile tree structure carries workspace presentation (split ratios, tab order, focus, filtered views).
Forcing these to mirror each other makes UI operations accidentally semantic and semantic operations accidentally visual.
A strong critique suggested one-way flow where tiles never mutate graph. That reduces accidental coupling, but taken literally it fails to model legitimate user intent from tile interactions.
Some tile actions are purely presentational (reorder, resize, focus). Others can be semantic if explicitly chosen by the user (close tab as close-node, deliberate grouping gesture).
So the practical boundary is not "tiles never mutate graph"; it is "tiles never mutate graph implicitly".
Even with graph-authoritative data, contradiction still appears if multiple systems mutate state directly:
- Servo callbacks
- Graph view interactions
- Tile interactions
- Keyboard shortcuts
- Restore/recovery paths
The real safeguard is a single mutation boundary (intent reducer/apply stage), not merely directional rhetoric.
Current docs mix statements like:
- webview set is source of truth,
- tile tree is authority for pane membership,
- graph is persistence/semantic model.
These can coexist, but only if scoped as separate authorities. Without that scope, it reads as competing primaries and invites implementation drift.
For collaboration, shared graph semantics and local workspace layout are a strong default:
- Shared: node identity/history/edges/intents.
- Local: pane layout, tab ordering, filtered projections.
If layout is tightly coupled to graph topology, collaboration conflicts increase with little semantic value.
-
GraphStore(semantic authority)
- Node identity (UUID)
- Node lifecycle state
- Edge semantics/provenance
- Per-node navigation/history metadata
-
WorkspaceStore(presentation authority)
- Pane hierarchy/splits
- Tab order and active tab per pane
- View filters/sorts/projection settings
- Local user preferences
-
RuntimeStore(ephemeral authority)
- Live webview instances
- Rendering contexts
- Texture caches and runtime-only resources
- Semantic operations
- Create node/tab
- Close/delete node
- URL/title/history semantic updates
- Create semantic edges (
Hyperlink,History,UserGrouped)
- Presentation operations
- Reorder tab
- Move tab across panes (presentation-only by default)
- Resize/split panes
- Focus/visibility/filter changes
- Runtime operations
- Instantiate/suspend/destroy webview instances
- Rebind rendering context
Cross-store mutation should happen only at reducer/apply stage.
Tile interactions should not create semantic graph changes implicitly.
Example policy:
- Drag tab to pane: presentation-only by default.
- "Group with" command/gesture: explicit semantic operation creating
UserGroupededge.
Required invariants:
- Every tile node reference must exist in graph.
- Graph node may exist without tile.
- URL change in same tab must not create a new node.
- New-tab action creates exactly one new node with stable UUID.
Allowed divergence:
- Same graph rendered in different pane layouts.
- Filtered/temporary workspace projections.
- Local layout differences across peers.
Persisting both is preferable to over-optimizing derivation:
- Graph persistence preserves semantics/history.
- Workspace persistence preserves UX continuity.
- On restore: validate workspace references against graph and prune stale entries.
- "Single source of truth" ambiguity across docs.
- URL identity remnants vs UUID direction.
- Same-tab URL change semantics vs polling-driven node creation behavior.
- Lifecycle naming drift (
ColdvsInactive). - Implicit assumption that pane cluster topology must track edge topology.
- Update wording to "semantic authority vs presentation authority vs runtime authority".
- Document explicit operation classes (semantic/presentation/runtime).
- State that structural parity is not a goal.
- Keep intent-based mutation as the only write path.
- Preserve optional future shared-workspace capability without coupling it to core graph sync.
Research only. No architecture decision is finalized by this file.