Keep a consumer bound where its data is; only a pin moves it (hq ADR 0232, issue 273)
Issue 258's fix let a mesh seat's holder elsewhere answer before this machine's own provider. Right for the resolver, which any provider answers alike; for the store's seat it re-bound every database consumer on a machine running its own store to the holder on another, each was given a fresh, empty database there, and nothing said so for twenty hours. - An offer says whether it keeps its consumers' data (`keeps-consumer-data`); unsaid, a provider that grants each consumer a credential does. For such a provision the seat's holder no longer overrules a provider beside the consumer; a pin still does. - Where each such consumer was sent is recorded (migration 0071). A resolution that would bind it elsewhere keeps the recorded provider and says the move; one whose provider is gone is refused, never answered by another. - A push says a kept move and raises it as an urgent condition at once; the self-check's D12 raises it every run, with a pinned move not yet sent as a warning and any unasked move as urgent.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
-- Where each consumer of a provision that keeps its data was bound (novox/hq ADR 0232, issue 273).
|
||||
--
|
||||
-- A consumer of a database is bound to its rows. What resolving chooses — the seat's holder, a pin,
|
||||
-- the providers assigned where — can change under a consumer without anybody meaning to move it, and
|
||||
-- on 2026-10-05 one change to how a seat's holder answers re-bound five database consumers on one
|
||||
-- machine to the store on another: each was made a fresh, empty database there, and nothing warned
|
||||
-- for twenty hours. The pair secrets were the only trace, and only because a new pair was minted.
|
||||
--
|
||||
-- One row per consumer and provision, written when a declaration carrying the binding is sent. A
|
||||
-- resolution that would answer the consumer from another provider keeps this one and raises an urgent
|
||||
-- condition; only a pin naming the other provider moves it, and the send that carries the move
|
||||
-- rewrites the row, keeping where it was in `moved_from`.
|
||||
--
|
||||
-- **The provider by name, not by reference.** A provider machine leaving the mesh must not take the
|
||||
-- record of where a consumer's data is with it: the data is still there, and a cascade would turn
|
||||
-- the record into nothing, which resolves as a binding never made — the silent move again.
|
||||
--
|
||||
-- Numbered 0071, past 0070, the highest on main or any open branch when this was written.
|
||||
create table binding (
|
||||
node uuid not null references node(id) on delete cascade,
|
||||
consumer text not null,
|
||||
provision text not null,
|
||||
provider_node text not null,
|
||||
provider_module text not null,
|
||||
-- When it was first bound where it is, and when a declaration last carried it.
|
||||
bound_at timestamptz not null default now(),
|
||||
sent_at timestamptz not null default now(),
|
||||
-- Where it was before a pin moved it, as `<node>/<module>`; null for a binding never moved.
|
||||
moved_from text,
|
||||
primary key (node, consumer, provision)
|
||||
);
|
||||
Reference in New Issue
Block a user