Chat views are templates — the first emission waits on no data

The platform rule (core Doc/GUI/DataBinding → Templates first, data later): a layout area is a template. It emits its whole control tree on the first render, the platform's loading shape covers whatever has not arrived, and the values are bound — never read on the hub and baked into the controls.

The shape every converted area uses

public static UiControl Thumbnail(LayoutAreaHost host, RenderingContext _)
{
    var template = BuildThumbnailTemplate(host.Hub.Address.ToString(), host.Localize("chat.noMessages"));
    return host.Workspace.GetMeshNodeStream()
        .Select(node => ProjectThumbnail(node, options, access))   // pure: node → view record
        .DistinctUntilChanged()                                      // an equal record is not republished
        .Bind(_ => template, ThumbnailViewId);                       // fed live into /data/{id}
}
Area Before Now
Thread History node + child query → hand-built HTML cards title bound to ThreadHistoryView (with the "Thread" fallback) + MeshSearch the GUI runs
Thread Thumbnail node → card with interpolated HTML template bound to ThreadThumbnailView
Message Streaming node → stack built per emission template bound to StreamingView; chips and delegation links are bound row lists
Message Overview node .Take(1) → editing or message tree, frozen both shapes declared; OverviewView chooses, live
Message Edit node .Take(1) → editor editor + Submit at once; draft buffer seeded when the message arrives
Message Thumbnail node → card with interpolated HTML template bound to MessageThumbnailView

The draft buffer behind the editors (/data/editText) is new input — what the person is about to resubmit — not a replica of the node: it is seeded once, read only by Submit, and never written back to the message. "Once" is per area: the Overview (for an editing prompt) and the Edit area each seed the buffer of their own layout host — each area is its own host with its own data store — so one seed can never reach the other's draft, and after the first seed a later emission of the node never writes the buffer again, so a typed draft has no writer on the hub to lose it to (pinned live, with a negative control, by TheDraftBuffer_IsSeededOncePerArea_AndALaterNodeEmissionNeverReseedsIt). Resubmit without an edit reads the message's current text at the click, not a render-time snapshot.

Nested slots that remain, and why

The changed-nodes lists — row-scoped Undo

The thread Header, the thread Changes page and the message's MessageChanges slot list the nodes a thread (or one message) changed: · v → v · Diff · Undo. They used to be controls rebuilt on the hub for every change — one closure per row — because a button inside a bound row could not say which row it was in. With row-scoped actions (core Doc/GUI/DataBinding → Row-scoped actions) they are templates:

Native clients: the React ItemTemplate does not yet stamp the row on a click, so a row's Undo is a no-op there until it does. The React chat renders messages from the thread node and embeds none of these areas.

Verified, not converted

Area Why it stays
Thread ThreadChat / Thread already a template: a static ThreadChatControl bound to a projected ThreadViewModel in /data
Thread Overview (progress), Streaming structure only — the node decides which message's area to embed; no value is baked
User/Threads inbox (ThreadInboxLayoutAreas) NOT converted to row-scoped actions on purpose: installed phone clients render it, and their ItemTemplate posts a click with no row, so per-row Close / Reopen / Delegated-tasks would stop working there. It waits for the React client to stamp the row (and for those clients to update)
Composer Composer, Selectors every value is already node-bound; the node is read only to choose the binding root (standalone composer or the thread's inline one)

Tests: MeshWeaver.AI.Test/ChatSurfacesAreTemplatesTest — every template has no deferred view and binds only projection properties; the projections make the decisions (the History title keeps the "Thread" fallback for a nameless thread); and against a real mesh the thread card's bound title follows a rename, the streaming view's chip and link rows follow the message, and a later node emission never re-seeds the draft buffer. MeshWeaver.AI.Test/ModifiedNodesRowActionsTest — the changed-nodes templates are static and the row binds only row properties; against a real mesh, clicking Undo in row k undoes change k for every k and nothing else; a no-row click undoes nothing (negative control); Undo all undoes every row.