Data access — one read path, one write path, every query names its partition

Audit of 2026-09-23. Every Source/*.cs in every module was re-read against the platform's Data Binding rules and the /gui + /mesh-data skills. This page records the rules the modules now follow, what the audit changed, and what it deliberately left alone.

The rules

You need to… Use Never
read the area's own node host.Workspace.GetMeshNodeStream() (parameterless — the local branch) the path overload on your own address
read other nodes hub.GetQuery("<module>-…:{what}", …) — a live synced query, every leg anchored GetMeshNodeStream(otherPath) (the permission probe can wedge), a one-shot mesh.Query(...).Take(1)
write a node's content GetMeshNodeStream(path).Update(node => …) — runs on the owning hub against the live node; only the diff travels IMeshService.UpdateNode(copy) — a whole node read moments earlier, written over whatever landed in between
create / delete a node IMeshService.CreateNode / CreateOrUpdateNode / DeleteNode (lifecycle)
edit a node's fields bind the control to the node: DataContext = LayoutAreaReference.GetMeshNodeDataContext(path) (RecordSupport.NodeText) seed a /data copy, then a Save button that reads it back
pick a node [MeshNode("namespace:<P> scope:descendants nodeType:<T>", …)] — one leg per partition [MeshNode("nodeType:<T>")]
show the result of a write nothing — every read is live, the write's echo repaints a "refresh" tick in /data that re-subscribes the reads

Every query names its partition — pickers included

The register/desk reads were anchored in #146 (Query reach). The pickers were not: 190 [MeshNode("nodeType:X")] attributes across 75 files named no partition. The store refuses such a query in CI (UnanchoredQueryException — the picker renders empty) and in production serves it as the UNION over every partition schema, logged at Error — the fan-out that seized both portals on 2026-08-31. Each now carries one anchored leg per partition the type's instances ship in: the type's home partition, plus ReinsuranceDemo where the worked book ships instances (Broker, Acceptance, Claims/Claim, Underwriting/Submission, the SST and IFRS 17 book types) or installs them at run time (Reinsurance/Cedent, via the Setup importer).

Known limit. A picker cannot name the viewer's own partition: the attribute's template offers {node.namespace}/{node.path} (the node's own path), not its partition. A demo copy installed into alice/ReinsuranceDemo therefore picks from the shipped partitions, not from alice. Closing that needs a {node.partition} template in core's MeshNodeAttribute.ResolveQueries.

Editors are bound to the node; commands are not editors

What the audit changed

Deliberately left alone