011: request or subscription is derived, not chosen

Asked what the distinction actually is, and the SQL half needed correcting
first: under exclusive ownership SQL runs against your own database and nothing
else, whatever transport a query might travel over. Both options are the mesh's
own channel and both ride the broker, so the transport is not the distinction.

The distinction is where the answer lives when you need it. A request asks at
the moment and waits — always current, costs a round trip, cannot answer when
the other side is down. A subscription keeps a local copy — instant, works
offline, as current as the last event received, and you must handle what you
missed.

What decides is not taste. ADR 0036 makes disconnection an ordinary situation
rather than an exception, so anything that must keep working while disconnected
CANNOT use a request: there is nobody to ask. And the converse — anything where
a stale answer is worse than no answer cannot use a subscription. A display can
lag; a decision about whether a grant is still valid cannot.

So an apparently open question turns out to be derived from a decision already
taken. What stays open is narrower: what a consumer does about the events it
missed while disconnected — replay from a point, ask once for a full picture and
resume, or rebuild. The question every projection has.

Also recorded: separate databases are required in the new design, and the shared
registry is a leftover rather than a pattern.
This commit is contained in:
2026-08-26 23:23:39 +02:00
parent 7e83723b7b
commit e71d532c2e
2 changed files with 33 additions and 5 deletions
@@ -256,11 +256,38 @@ its dependency on the registry shrinks to a single table.
What remains is a handful of genuine cross-context reads, small enough to enumerate rather than
estimate. **The rule holds.**
### What it still does not answer
### Request or subscription, and what decides
Whether those remaining reads want an **interface** or **events**. A consumer asking *which
nodes exist* at the moment it needs to know is a request; one that must react *when a node
appears* is a subscription. Some will want both, and nothing here says which.
The remaining cross-context reads need one or the other. **Neither is SQL** — under exclusive
ownership a module runs SQL against its own database and nothing else, whatever transport a
query might travel over. Both options are the mesh's own channel, and both ride the broker
([ADR 0001](../../02-DECISIONS/0001-nodes-communicate-over-a-broker.md)), so the transport is
not the distinction.
**The distinction is where the answer lives when you need it.**
| | request | subscription |
|---|---|---|
| you ask | at the moment you need to know | never — you are told |
| the answer lives | on the other side | in your own store |
| freshness | always current | as current as the last event you received |
| when the other side is down | you cannot answer | you answer from your copy |
| what you must handle | a round trip that can fail | events you missed while you were down |
**What decides is not taste.** [ADR 0036](../../02-DECISIONS/0036-a-node-is-a-managed-machine.md)
makes disconnection an ordinary situation rather than an exception. So:
> **Anything that must keep working while disconnected cannot use a request** — there is nobody
> to ask. It needs a local copy, which means a subscription.
And the converse: anything that must be *correct at the instant of asking*, where a stale answer
is worse than no answer, cannot use a subscription. A display can lag. A decision about whether
a grant is still valid cannot.
That turns an apparently open question into a derived one. What remains genuinely open is
narrower: **what a consumer does about the events it missed** while it was disconnected — replay
from a point, ask once for a full picture and resume, or rebuild from scratch. That is the same
question every projection has, and nothing in the record answers it yet.
## A migration belongs to the consumer and runs on the provider