012: on conflict, keep the machine's configuration
Reversed by the operator, and both directions are recorded because the reasoning for each is the useful part. What is already on the machine stays, the conflict is flagged, adoption completes. This buys non-destructiveness by construction: the class that made the opposite rule dangerous — a storage driver against the filesystem it is actually on, a data directory pointing at a mount that exists — cannot arise, because nothing tied to the machine's physical reality is overwritten. It exposes the mirror. The mesh's configuration is not only preference; some of it is what a module needs to function. Keeping the machine's version there produces a module that is installed and does not work, which is 04-ISSUES/007 arriving from a direction that issue did not anticipate. And a fleet where every node kept its own settings is one where a module works on one node and fails on another with nothing able to say why. So neither direction is right as a blanket, and the question is not whose configuration wins. It is whether the module REQUIRES the setting or merely PREFERS it — required contradictions cannot be kept without breaking the module, preferences should always yield to what is there. That is a property of the module's declaration rather than of the adoption algorithm, which makes it one more thing the graph would carry. Until modules can say which of their settings are load-bearing, adoption is defaulting in the dark, and the default chosen is the one that does not break the machine it is adopting.
This commit is contained in:
@@ -110,30 +110,41 @@ Conflicts are **flagged, not resolved**. That is the same principle the declarat
|
|||||||
already applies — name every problem at once, to somebody who can act on it — at a larger
|
already applies — name every problem at once, to somebody who can act on it — at a larger
|
||||||
scale, and applied to a case where refusing wholesale would be worse than proceeding.
|
scale, and applied to a case where refusing wholesale would be worse than proceeding.
|
||||||
|
|
||||||
### On conflict, the mesh's version is installed
|
### On conflict, the machine's configuration is kept
|
||||||
|
|
||||||
Decided by the operator: where the existing configuration and the mesh's disagree, **the mesh's
|
Decided by the operator, after first deciding the opposite — recorded that way because the
|
||||||
version is installed**, the conflict is flagged, and it is reconciled afterwards.
|
reasoning for each direction is the useful part.
|
||||||
|
|
||||||
The reasoning is that the mesh's configuration is known to work, the machine's is not, and a
|
Where the existing configuration and the mesh's disagree, **what is already on the machine
|
||||||
half-adopted machine is a state nobody understands. Adoption therefore always **completes** —
|
stays**, the conflict is flagged, and it is reconciled afterwards. Adoption always **completes**
|
||||||
flags inform, they do not block — and the original is kept, so nothing is unrecoverable.
|
— flags inform, they do not block — and *adopted with open questions* prevents nothing. The
|
||||||
|
node is a node.
|
||||||
|
|
||||||
That also answers what *adopted with open questions* prevents: nothing. The node is a node.
|
**What this buys.** Adoption becomes non-destructive by construction. The class of conflict that
|
||||||
|
made the opposite rule dangerous — a storage driver against the filesystem it is actually on, a
|
||||||
|
data directory pointing at a mount that exists — cannot arise, because nothing tied to the
|
||||||
|
machine's physical reality is ever overwritten. A machine in use keeps working exactly as it
|
||||||
|
did.
|
||||||
|
|
||||||
**One class of conflict this should not cover, and it is the open part.** *Known to work* is
|
**What it exposes, which is the mirror of what it fixes.** The mesh's configuration is not only
|
||||||
true of the mesh's configuration in isolation, not on this machine. Most disagreements are
|
preference. Some of it is what a module needs in order to function at all. Keeping the machine's
|
||||||
preference — tuning, logging, a mirror — and overwriting them is right. A few are tied to what
|
version there produces a module that is installed and does not work — *an installed package is
|
||||||
is physically present: a container runtime's storage driver against the filesystem it is
|
not a capability*
|
||||||
actually on, a data directory pointing at a mount that exists. Installing the mesh's version
|
([04-ISSUES/007](../../04-ISSUES/007-an-installed-package-is-not-a-capability/00-report.md))
|
||||||
there does not discard a preference; it can make existing data unreadable, and restoring the
|
arriving from a direction that issue did not anticipate. And a fleet where every node kept its
|
||||||
configuration file afterwards does not undo that.
|
own settings is a fleet where a module works on one node and fails on another with nothing in
|
||||||
|
the mesh able to say why.
|
||||||
|
|
||||||
So the default is settled and the exception is not: the exception is not *there is a conflict*
|
**The distinction that dissolves both rules.** Neither direction is right as a blanket, because
|
||||||
but *applying ours would destroy something a configuration backup cannot restore*. Identifying
|
the question is not *whose configuration wins*. It is whether the module **requires** the
|
||||||
that class is open, and it is the one place where this repository's oldest rule — the incident
|
setting or merely **prefers** it — required contradictions cannot be kept without breaking the
|
||||||
that came from a tool acting on a path it did not own — argues for refusing rather than
|
module, and preferences should always yield to what is already there.
|
||||||
proceeding.
|
|
||||||
|
That is a property of the module's own declaration rather than of the adoption algorithm, which
|
||||||
|
makes it one more thing the graph would carry
|
||||||
|
([research 011](../011-the-module-graph/00-overview.md)). Until modules can say which of their
|
||||||
|
settings are load-bearing, adoption is choosing a default in the dark, and the default chosen
|
||||||
|
here is the one that does not break the machine it is adopting.
|
||||||
|
|
||||||
## Open questions
|
## Open questions
|
||||||
|
|
||||||
@@ -141,9 +152,10 @@ proceeding.
|
|||||||
|---|---|
|
|---|---|
|
||||||
| What is the closure for a one-node mesh? | The skeleton asserts four pinned services. [Research 006](../006-mesh-from-scratch/00-overview.md) already asks whether it is four or five and does not answer. A graph gives a computed answer instead of an asserted one, which is [research 011](../011-the-module-graph/00-overview.md). |
|
| What is the closure for a one-node mesh? | The skeleton asserts four pinned services. [Research 006](../006-mesh-from-scratch/00-overview.md) already asks whether it is four or five and does not answer. A graph gives a computed answer instead of an asserted one, which is [research 011](../011-the-module-graph/00-overview.md). |
|
||||||
| Is "tier" the same thing as a graph level? | Tiers were named as a bootstrap order. If the closure is computed, tiers may be a derived view of the graph rather than a separate concept — or they may be a coarser boundary that survives for a different reason. |
|
| Is "tier" the same thing as a graph level? | Tiers were named as a bootstrap order. If the closure is computed, tiers may be a derived view of the graph rather than a separate concept — or they may be a coarser boundary that survives for a different reason. |
|
||||||
| ~~What happens when existing configuration contradicts what the mesh needs?~~ | **Answered** — the mesh's version is installed, the conflict is flagged, and it is reconciled afterwards. The original is kept, so nothing is unrecoverable. |
|
| ~~What happens when existing configuration contradicts what the mesh needs?~~ | **Answered** — the machine's configuration is kept, the conflict is flagged, and it is reconciled afterwards. |
|
||||||
| ~~Do flags block, or only inform?~~ | **Answered** — they inform. Adoption always completes, and the node is a node. |
|
| ~~Do flags block, or only inform?~~ | **Answered** — they inform. Adoption always completes, and the node is a node. |
|
||||||
| Which conflicts are destructive rather than merely disagreements? | The one exception to the rule above. Overwriting a preference is right; overwriting something tied to the machine's filesystem or existing data can make that data unreadable, and a configuration backup does not undo it. Identifying that class is open. |
|
| Can a module say which of its settings are load-bearing? | The question that dissolves the conflict rule rather than choosing a side. A setting the module *requires* cannot be kept from the machine without producing something installed and broken; a setting it merely *prefers* should always yield. Until a module can say which is which, adoption is defaulting in the dark. Belongs with the graph. |
|
||||||
|
| How is a flagged conflict reconciled, and by whom? | The briefing hands it to a session. What that session is empowered to change, and whether the resolution is recorded so the next adoption does not re-raise it, is undecided. |
|
||||||
| Where does the kept original live, and for how long? | Whether it is recorded in the node's state so adoption is visibly reversible, and whether it is returned when the mesh stops managing the thing. |
|
| Where does the kept original live, and for how long? | Whether it is recorded in the node's state so adoption is visibly reversible, and whether it is returned when the mesh stops managing the thing. |
|
||||||
| What shape is a briefing? | Structured enough to be acted on, prose enough to be read. It is the first thing a session on a new node sees, which makes it an interface rather than a log. |
|
| What shape is a briefing? | Structured enough to be acted on, prose enough to be read. It is the first thing a session on a new node sees, which makes it an interface rather than a log. |
|
||||||
| Does owning a package mean owning its version? | Owning configuration and owning the package are different scopes. The second means the mesh decides which version is installed, and that decision then has to survive the machine's own package manager updating it. |
|
| Does owning a package mean owning its version? | Owning configuration and owning the package are different scopes. The second means the mesh decides which version is installed, and that decision then has to survive the machine's own package manager updating it. |
|
||||||
|
|||||||
Reference in New Issue
Block a user