Every view is data-bound (core: Doc/GUI/DataBinding → Templates first, data later). A node page in this pack used to subscribe to GetMeshNodeStream() on its hub, wait, and only then build its controls out of the record. Until the owning hub answered the page was a spinner, and each emission rebuilt the whole tree. Each converted page now has three parts.

The shape

Part What it is
Template BuildTemplate… (pure) returns the whole tree. Every view in it is a control, and every value is a JsonPointerReference into a projection record. A section the record may lack is in the tree anyway; its style is bound and is display: none; when the projection says it is absent. The tree's shape never depends on the data.
Projection Project(…) (pure) turns the node's content into that record (ApiTokenView, ReleaseView, NotificationView). It holds the decisions the builders used to make inline: which sections show, the status label and colour, the toggle's label, the viewer-zone instants. The area returns stream.Select(Project).Bind(_ => template, ViewId), so the framework feeds /data/{ViewId} live.
Slots Two platform pieces still take a LOADED node. The header is MeshNodeLayoutAreas.BuildHeader. The property form is OverviewLayoutArea.BuildPropertyOverview, which picks its fields from the content's runtime type. Each renders in a nested area (NodePageSlots.HeaderArea = PageHeader, NodePageSlots.PropertiesArea = PageProperties) with SpinnerType.Skeleton, so the page around it is already there. When core offers path-bound forms of the two, NodePageSlots is the one place to swap them in.

A page gated on Read (GroupMembership) keeps its gate as DATA. The access-denied notice and the body are both in the template. NodePageSlots.ReadGated binds their styles to the viewer's effective permission.

The bound style hides; it does not withhold. Every viewer receives the body, so a read-gated body holds nothing of the node: only static controls and references to slots. The node's content is served by the slots, and each is an area of its own that a client can ask for with nothing but the node's address. Two things keep it from a viewer without Read:

Node content in the page

Until the projection arrives, the bound fields draw the platform's loading shape (LoadingShape). A node that has not loaded projects to "every section hidden". A node that loaded without the expected content projects to the notice the page always showed.

Converted

Page Areas
API token Overview, Thumbnail
Release Overview
Notification Overview, Thumbnail (a node without a notification falls back to the path-only platform card)
GroupMembership Overview (header and property form in their slots)
Access Control (node-wide) the page; the title is bound to the node name, and the add / advanced sections to the admin probe
Groups (node-wide) the page; the title and "+ Add membership" are bound, and the inherited and local lists render in the GroupsInherited / GroupsLocal slots
Group Overview (the member grid is bound to the live member query); Edit (the bound title, with member rows — one delete action each — in the EditMembers slot)
AccessAssignment Overview (a read gate as data; the detail, with one node-bound editor per role, renders in the AssignmentDetail slot)
Activity Overview (header, progress shape, Cancel / Re-run bound to ActivityView; the log rows and the script's rendered result are a deferred view of the same host), Cancel (bound visibility and disabled state)
Versions / VersionDiff (node-wide) Versions: the back link and title are the frame, and the picker (it shares the From/To selection in this host's /data) is a deferred view beside it. VersionDiff: the back link alone is the frame — the title names the compared versions, so it renders inside the deferred comparison (redline or side-by-side, chosen by what the versions hold); a deployment that retains no history shows its note inside the same frame

A deferred view beside a static frame is the shape for a body that genuinely computes and has to stay in the page's own host, such as the version picker, whose row buttons write the selection the compare bar reads. Such a body is never the page's ONLY content: the frame renders first.

Not yet

Unit Why
Activity Progress This is the code cell's output pane. MeshWeaver.AI.Test (CodeCellOutputCaptureTest) pins its control shape (indicator, log and result as root areas). Its conversion goes with the code-cell surface.
CodeViews (Overview, RunFromBuffer, edit content) The code cell editor and its run loop. Its buffer, staleness and dispatch are pinned by six suites, and it needs its own pass.
DeleteViews (Delete, StartDelete, FinishQuerySetDelete) Delete already emits a loading placeholder first (StartWith). Its reads are the permission gate and the descendant count, which the confirmation states. The other two hits are click-time reads (where to land after a delete). Not converted here.
Space Overview The landing page. Its body markdown carries @@ embeds, and the catalog and header decisions read the content. It needs a pointer-bound body that the document export can still read (core B1, part 2, has the same open point).
PartitionSyncAdmin An admin tab (P3) whose per-partition select buttons are the data's structure.
PinnedThumbnail Verified, not converted: it already draws a card-shaped skeleton before the node arrives. The scanner hit (UpdatePinnedPaths) is the unpin WRITE in a click action.

Read and left as they are: the AccessAssignment Thumbnail and the GroupMembership Thumbnail. Every value in the AccessAssignment row is already node-bound: the subject is a path-bound card and each role is a MeshNodeRoleEditorControl. The row reads the node only to choose its STRUCTURE (how many role rows there are, and the edit actions the viewer gets). A slot per row would double the area subscriptions of every access list. The GroupMembership card shows the membership's display name and its group list. The path-only card reads the node's own Name and Description instead, so it would say something else. Both need a platform card whose title and abstract bind by pointer.

A page that used to BUILD an admin-only section only for an admin now carries it in the template and binds its visibility. The section and its click actions are therefore in every viewer's tree, and a viewer can click what a style hides. So each action it offers is refused where it executes, never by being hidden:

The Group Edit page's "Invite by Email" is the same shape and was open before this change set: the Edit area is served to every viewer who may READ the group, and for an address with no account InviteToGroup writes the Invitation and the deferred add-to-group — membership and role — as System. GroupLayoutAreas.InviteAllToGroupAs (landed on main by MeshWeaver.Plugins#2710) runs only for a caller who may add members and manage access on the group (Create and Delete). Measured through the real click in GroupInviteAuthorizationTest: before the check a reader's click answered "1 invited … role Admin" and left both records; with it the reader is refused and leaves nothing, and the admin's clicks invite as before.

The same holds for a slot a read gate hides: AssignmentDetail builds through NodePageSlots.ForReader. Before the projection arrives, a section with a bound style draws the loading shape — a text-free pulse with pointer input off (LoadingShape).

The two Group pages publish under two ids, groupView and groupEditView: one id is one shape. GroupView compares its member rows by content, so the Overview republishes only when what it shows changed. A group's description is user text and is shown by a label, which renders its value as text.

The text these pages used to carry inline now lives in the module-owned table NodeChromeTexts (English and German). Strings that were already catalog keys stay catalog keys.

Pinned by

src/MeshWeaver.Graph.Views.Test/NodeChromeTemplatesTest.cs, AccessTemplatesTest.cs and AccessControlLayoutAreaTest.AccessControlAndGroups_AreTemplates_… check these things:

Negative control: adding one deferred view to a template fails EveryViewIsStatic.

Deploy

These views are compiled into the pack's assembly, so a new activation picks them up. A node hub that is already running keeps the old views until it is disposed. After the roll, recycle the NodeTypes ApiToken, Release, Notification, GroupMembership, Group, AccessAssignment and Activity; the dispose cascades to their live instances. The node-wide Access Control, Groups and Versions areas reach a node when that node's hub is next activated.