A one-node lookup reads the owner, never a query cache

MeshQueries.FindNode(hub, path) is the Store's single-node read: the cover reads PluginContent through it, coupons read CouponContent, the installer reads its manifest, and every PluginGate verify-before-write decision — "is this grant still missing?", "did my write become durable?" — is one of its answers.

It reads the node from its OWNER. A listing answers EXISTENCE (empty on absent, so a point read never lands on a path that is not there); the per-node stream answers CONTENT. That is the composition Doc/Architecture/CqrsAndContentAccess prescribes for a node that may not exist yet, and it is the only shape in which the answer cannot be older than the node.

What it used to be, and what that cost

It used to be one synced query: hub.GetQuery("Store.Node:{path}", "path:{path}") — one node's content out of a live collection. Three properties of that transport compose into a defect:

  1. The chain is cached for the life of the PROCESS. MeshNodeStreamCache.GetQueryRaw builds it as Replay(1).AutoConnect(1) and keeps it in a registry that is never rebuilt. The FIRST answer is therefore the answer every later caller in that process replays.
  2. A cold first answer is an ordinary outcome, not an error. MeshQuery's merge counts a provider that completes without an Initial as an EMPTY Initial by contract — the alternative was a consumer that hangs — so a provider that gives up under load hands the chain "there is nothing there", permanently. (Routing has its own cold shape: GetDelegateForPath answers null while a partition's schema adapter is unresolved, and the query takes the cross-schema route instead of its own. Which of these fired on memex-cloud is NOT established — what is measured is the RESULT, below, and that a restarted replica does all of this at once while every plugin hub activates.)
  3. Nothing corrects it. A gating pass re-writes an unchanged node, the upsert is a NO-OP at the store (IsNoOpUpsert), and a no-op publishes no change — so the one event that would refresh the chain never happens. The wrong answer is now permanent for that replica.

Measured on memex-cloud on 2026-09-16, in the 24 minutes after the 21:24Z restart (the incident is Admin/_LogIncident/d1cd36f53a5f3a6c, 11,927 occurrences, and it went quiet again afterwards):

what the gate logged, at Error what the store held
Codex, Antigravity, Grok, OpenCode: write did NOT become durable for …/_Access/Public_Access, …/Anonymous_Access — a provisioned partition lost a write all eight grants present at version 1, written 2026-09-13, untouched since
Feedback: same line for Feedback/_Submissions/_Access/* both denies present at version 1, written 2026-08-03, untouched since
Governance, BuildServer, WhatsApp, iMessage: reconcile is NOT CONVERGING — rewrote …/_Policy each _Policy in the exact shape PolicyMatches wants, versions 2–3, no version written on 09-16 at all

Nine of the ten retained samples name a node that was durably present, in the shape the pass wanted, for days. The value was never stale at the owner; it was stale in the lens — and SyncedQueryMeshNodes says so in its own summary: "for single-node content reads on a known path use GetMeshNodeStream instead — the synced collection is for live collections, not for fetching one node by path."

The shape now

What this does not fix

The other half: a write's outcome is the owner's ANSWER

Reading the owner fixes the read that decides whether to write. It does not fix a read taken immediately AFTER a write, and that one cannot be fixed by choosing a better seam: the per-node stream handle and the synced query both replay a cached last-known value, so a read microseconds after a write legitimately answers with the pre-write state. So the gate no longer re-reads at all. CreateOrUpdateNode emits the node as its owner then holds it — created, merged, or the untouched existing one when the upsert was a no-op — and PluginGate.VerifiedWrite, EnsureEntitlementPrivacy and EnsureEntitlementRootPrivacy judge that. It is race-free, one round trip cheaper, and the owner is the one component that cannot be looking at a stale copy of its own node.

What that verdict deliberately does not claim is DURABILITY — the owner accepting a shape is not the store keeping it. That statement belongs to the next pass: a path this hub wrote, whose fresh read finds the shape missing again, is the store losing writes (or a partition that has none), and GatingWatcher.md describes how the watcher parks and classifies it. The privacy prerequisites fail CLOSED, so the same race there refused an acquisition on a partition that was already private.

Pinned by PluginGateLandedVerdictTest (MeshWeaver.PluginCatalog.Test): a cold lens that never saw the node must not make the pass write, fail, or report a durable node as lost — the test poisons the lens exactly the way a replica does, by letting a SECOND host over the same store write the shape, which is the topology OrleansTestBackingStore models ("what is shared is the STORE, not the change feed").

Reconnecting…
The server was updated. Reloading the page to pick up the latest version.