ADR 0262: record the lenient read of stored manifests and the marked defaults layer
A stored manifest read strictly would fail the whole catalogue after a controller rollback, and a node called default would lose its layer. Also scope the default, retire tunable, and list the new checks.
This commit is contained in:
+2
-1
@@ -66,7 +66,7 @@ is listed under [Homonyms](#homonyms), with the qualified form each domain uses.
|
||||
**Purpose.** To say what one module is, in the one document every other domain reads.
|
||||
**Recorded in** the catalogue, one manifest per module. **Upstream of** every other domain; its words
|
||||
are a published vocabulary, fixed by the manifest's schema. **Decided by** ADR 0040, 0126, 0174, 0188,
|
||||
0207, 0236.
|
||||
0207, 0236, 0262.
|
||||
**Uses:** module, seat, provision (Provisioning), data class (Data), health (Health and repair).
|
||||
|
||||
- **manifest** — the file a module is defined by (`module.json`): what it is, what it provides and
|
||||
@@ -89,6 +89,7 @@ are a published vocabulary, fixed by the manifest's schema. **Decided by** ADR 0
|
||||
software and only tuned per node: a font size, a width
|
||||
([ADR 0262](../02-DECISIONS/0262-a-preference-has-a-default-in-its-manifest-and-the-operators-own-value-has-none.md)).
|
||||
A setting with no default is the operator's own value: a domain, an identity.
|
||||
*Not:* ~~tunable~~ (hq)
|
||||
- **kept region** — a marked block in a managed file the mesh writes *into*, where the operator's own
|
||||
lines survive every send and are given back when the module goes (ADR 0174). The other way a node
|
||||
varies a module.
|
||||
|
||||
+26
-4
@@ -70,9 +70,10 @@ when nothing sets it, as ADR 0155 decided. This record narrows that refusal to e
|
||||
does not change it.
|
||||
|
||||
**The settings override the default in a fixed order:** the manifest's default, then the mesh-wide
|
||||
settings, then the node's, and the last one wins. A default fills `${setting:<key>}` wherever it
|
||||
appears: a file's content, a contribution, a served fact. It is never merged into a mergeable JSON
|
||||
file as a key, because that file's content already holds its own defaults, and a key laid over every
|
||||
settings, then the node's, and the last one wins. A default fills `${setting:<key>}` in a file's
|
||||
content, a contribution and a served fact. A module's zone name is the one served value it does not
|
||||
fill: that name is the operator's own and has no default. A default is never merged into a mergeable
|
||||
JSON file as a key, because that file's content already holds its own defaults, and a key laid over every
|
||||
such file is the leak [issue 168](../04-ISSUES/168-a-setting-reaches-every-file-and-contribution/00-report.md)
|
||||
describes.
|
||||
|
||||
@@ -89,6 +90,17 @@ the mesh, or the node. Where the mesh or the node overrides a default, the defau
|
||||
**A default must be read by something.** A declared key that no file, contribution or served fact asks
|
||||
for is refused, because a default that reaches nothing is the same mistake as a stray setting.
|
||||
|
||||
**The defaults are a layer of their own, marked as one.** A node's settings are named after the node,
|
||||
and a node may be called anything, `default` included. The defaults are told apart by a mark on the
|
||||
layer, never by its name.
|
||||
|
||||
**A stored manifest is read leniently; a manifest being registered is read strictly.** Registration
|
||||
and the module check refuse a key the controller does not know, as before. Reading the catalogue the
|
||||
store already holds sets such a key aside, says so once in the controller's log, and keeps the rest.
|
||||
Without this, the first manifest to use `settings` would make every older controller fail to read the
|
||||
whole catalogue, and with it every plan and every send on every node, the moment the controller was
|
||||
rolled back. The same holds for every field a later record adds.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The notifier's font size and width become preferences with today's values as defaults, and the
|
||||
@@ -96,6 +108,11 @@ for is refused, because a default that reaches nothing is the same mistake as a
|
||||
- A manifest that declares `settings` is refused by a controller older than this record, which reads
|
||||
manifests strictly. The controller change is sent first, and a catalogue change that uses the field
|
||||
merges only after it is live.
|
||||
- **The lenient read protects rollbacks to this controller and later ones, not to earlier ones.** Once a
|
||||
manifest in the store uses `settings`, rolling the controller back to a version before this record
|
||||
still fails the catalogue read. Rolled back to this version or a later one, the module's defaults are
|
||||
set aside with the field, so a module that relies on a default is left out of its machine's
|
||||
declaration by name, and the rest of the machine is composed.
|
||||
- **What got harder:** a module author now decides, for every `${setting:…}`, whether the value is a
|
||||
preference or the operator's own, and says so. The check below catches the clear mistakes by the
|
||||
key's name and by the value naming an installation. It cannot catch a preference default that is
|
||||
@@ -112,12 +129,17 @@ for is refused, because a default that reaches nothing is the same mistake as a
|
||||
| Rule | Checked by |
|
||||
|---|---|
|
||||
| A default is declared only for a preference, with why | The controller's manifest parser, run on every catalogue pull request as the module check: a `settings` entry is refused without `kind: preference`, without a default, with an empty or non-scalar default, or without `why` (`TestTheParserTakesAPreferenceAndRefusesTheRest`) |
|
||||
| The operator's own value has no default | The same parser refuses a default for a key whose name says it is the operator's (domain, host, issuer, url, mail, address, identity, login, user, account, password, secret, token, credential), and the installation check of ADR 0155 already refuses a default naming a domain or a public address. `TestAnOperatorsValueWithoutADefaultIsStillRefused`: an unset key with no default is still refused by name |
|
||||
| The operator's own value has no default | The same parser refuses a default for a key that has, as a whole word, a name of the operator's own value (among them domain, host, zone, url, ip, mail, address, user, owner, uid, password, secret, token, key, and client-id), and the installation check of ADR 0155 already refuses a default naming a domain or a public address. `TestAnOperatorsValueWithoutADefaultIsStillRefused`: an unset key with no default is still refused by name |
|
||||
| The node over the mesh over the default | `TestTheNodeOverTheMeshOverTheDefault`, and `TestAComposedMachineGetsTheDefaultAndTheNodesValue` through a machine's whole composition |
|
||||
| A default never becomes a key of a mergeable file | `TestADefaultIsNotMergedIntoAJSONFile` |
|
||||
| A key with a default is accepted by `settings` | `TestAKeyWithADefaultIsNotStray` |
|
||||
| A default reaches something | The parser refuses a declared key that nothing asks for (`TestTheParserTakesAPreferenceAndRefusesTheRest`, "read by nothing") |
|
||||
| Every value says where it came from | `TestEveryValueSaysWhereItCameFrom` and `TestSettingsSayWhereEachValueComesFrom` |
|
||||
| The operator's word is a whole word of the key | `TestAKeyIsTheOperatorsByAWholeWord`: `max-tokens`, `show-hostname`, `users-per-page`, `mailbox-size` are preferences; `api-key`, `oauth-client-id`, `public-ip`, `dns-zone` are not |
|
||||
| A default is read by the installation check | `TestTheInstallationCheckReadsADefault`, including a setting called `description` |
|
||||
| A default fills a contribution and a served fact, and never replaces a contribution's own value | `TestADefaultFillsAContributionAndAServedFactButNotALiteral` |
|
||||
| A node called `default` is a node | `TestANodeCalledDefaultIsANodesLayer` |
|
||||
| A stored manifest with an unknown key is read, and registration refuses it | `TestAStoredManifestWithAnUnknownKeyIsReadAndRegistrationRefusesIt` |
|
||||
| Nothing changes where no machine sets a value | The notifier's manifest test fills the file with the defaults and finds today's lines; live, `mesh-controller.plan` for the workstation shows no change to the notifier's file after the catalogue change is sent |
|
||||
|
||||
## References
|
||||
|
||||
Reference in New Issue
Block a user