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.
32 lines
1.9 KiB
SQL
32 lines
1.9 KiB
SQL
-- 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)
|
|
);
|