From 04de5c3b3089022961474f590120914d551f24ec Mon Sep 17 00:00:00 2001 From: jochens Date: Thu, 12 Nov 2026 23:58:42 +0100 Subject: [PATCH 1/5] Design 42 zfs-owns-zfs: the apply writes /etc/hostid and reads it back, as ADR 0679 version 17 says No template writes the four binary bytes of /etc/hostid, so it is no resource and the composer cannot see a second writer: the apply guards it by the pool's label, reads it back, is unhealthy on a mismatch, and keeps the file on leave. --- .../01-to-be/42-milestones/zfs-owns-zfs.md | 64 +++++++++++-------- .../42-the-machines-modules-in-order.md | 17 +++-- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs.md b/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs.md index 0a39f100..471c3d78 100644 --- a/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs.md +++ b/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs.md @@ -160,13 +160,20 @@ capabilities of §4 (a reader's capability the delivery plan derives, ADR 0614 `/etc/zfs/zed.d` is not read while the drop-in holds. The mesh creates no symlinks. The node-engine restarts `zfs-zed.service` on a change of the drop-in, a handler or `zed.rc` (`restart-on`). Checked by the manifest test (no link resource, each handler's condition). -15. **The node's ZFS id** (ADR 0679 §1, §3, §4). `/etc/hostid` holds four bytes, which no template writes, so the apply - (§18) writes it with ZFS's own writer, `zgenhostid -f `, only while `hostid` is set, and only when the pool's - label (`zdb -C `, its `hostid`) is 0 or equals the value: then the next boot imports without `zpool import - -f`. Otherwise it writes nothing and emits `config.refused` naming why ("the pool's import would need -f"). Before - the Approve, the value's description and `zfs_config` say the change needs a check of the pool's import at the next - boot; the module never reboots. After the reboot, `zfs_pools` shows the pool imported. Emits `config.applied` with - target `file`. Checked by §31 (unset: no `zgenhostid`; a label of another id: refused; 0 or equal: one run). +15. **The node's ZFS id** (ADR 0679 §1, §3, §4, §17). `/etc/hostid` holds four bytes, binary, which no template writes, + so it is no resource of the manifest and the apply (§18) writes it with ZFS's own writer, `zgenhostid -f `, + only while `hostid` is set, and only when the pool's label (`zdb -C `, its `hostid`) is 0 or equals the value: + then the next boot imports without `zpool import -f`. When the label shows another value, or cannot be read, it + writes nothing and emits `config.refused` naming why ("the pool's import would need -f", "the pool's label cannot be + read"). Before the Approve, the value's description and `zfs_config` say the change needs a check of the pool's + import at the next boot; the module never reboots. After the reboot, `zfs_pools` shows the pool imported. Emits + `config.applied` with target `file`. The apply reads `/etc/hostid` back at every start and after every write: while + `hostid` is set, a value there other than the set one emits `config.refused` naming it, because the node-engine's + composer cannot see a second writer of a file that is no resource. Each refusal of this line makes `zfs_health` + unhealthy (§29), naming the key and why, until an apply finds the label and the file agreeing with `hostid`, or + `hostid` is unset. No resource or template of the manifest writes `/etc/hostid`. Checked by §31 (unset: no + `zgenhostid`; a label of another id, or one that cannot be read: refused; 0 or equal: one run; a file holding + another value: refused; unhealthy, then healthy again; no manifest resource for the file). ## The pool @@ -194,7 +201,7 @@ capabilities of §4 (a reader's capability the delivery plan derives, ADR 0614 waits-on, since}. A declared device that is not present is a wait. Each change is read back from `zpool status -P` and emitted. Checked by §31's convergence tests (the empty list among them) and acceptance test 2. -18. **The apply: who, when, and what wakes a wait** (ADR 0679 §9). A `process` resource `zfs-config-apply`, `run: +18. **The apply: who, when, and what wakes a wait** (ADR 0679 §9, §17). A `process` resource `zfs-config-apply`, `run: ./zfs-tools apply`, as root, oneshot, ordered after `zfs-import.target`, enabled at boot, with `restart-on` the config file (§9); it converges §15 to §17 and writes the ARC values live. It holds an exclusive lock on `/run/zfs-tools/apply.lock`; a second start waits for it. It converges nothing while a scrub or resilver runs on @@ -207,7 +214,7 @@ capabilities of §4 (a reader's capability the delivery plan derives, ADR 0614 to `/sys/module/zfs/parameters/zfs_arc_max` and `zfs_arc_min` as well as to §12's file, and reads both back; each `module-options` entry whose live value differs is a warning naming it, "takes effect at the next load of the kernel module", never success and never unhealthy. -19. **The call-site test** (ADR 0679 §7). Every command the bundle runs is built by one of its argument functions, and +19. **The call-site test** (ADR 0679 §7, §17). Every command the bundle runs is built by one of its argument functions, and the test (`TestTheBundleRunsOnlyReadingVerbsSnapshotAndScrub`, renamed `TestTheBundleRunsOnlyTheFormsOfADR0679`) allows only: `zpool add cache|log`, `zpool remove` of a cache or log device, `zpool set`, `zfs set` and `zfs inherit` of a listed property, `zfs snapshot`, `zfs set mesh:schedule=` on a ZFS snapshot named `mesh-`, @@ -217,7 +224,9 @@ capabilities of §4 (a reader's capability the delivery plan derives, ADR 0614 data vdevs, spares, special and dedup devices, `upgrade`, a dataset's destroy, `rollback`, `rename` and `clear` are never run (each an act of its own, asked of the operator). The same test pins the module's other root forms: `wipefs --no-act `, `zdb -l `, `zdb -C `, `zgenhostid -f `, `udevadm monitor --udev - --subsystem-match=block` and `systemctl show`. Fate: the README's list of allowed forms is replaced by this one. + --subsystem-match=block` and `systemctl show`, and refuses every other `zgenhostid` or `zdb` form: `zgenhostid` + only as `-f` with the value §11 validated, `zdb` only as these two reads. Fate: the README's list of allowed forms + is replaced by this one. ## The scheduled run and ZFS snapshots @@ -302,22 +311,27 @@ capabilities of §4 (a reader's capability the delivery plan derives, ADR 0614 `zfs.conf`, `/etc/zfs/mesh-zed.d` and the drop-in are removed, and before leaving `zfs_config` says that the next load of the kernel module uses ZFS's defaults. The distribution's scrub and trim timers are put back as the module's declaration found them, started and enabled again where it stopped or disabled them. Pool and dataset - properties and devices stay as the last apply set them, also on a rollback (§8). + properties and devices stay as the last apply set them, also on a rollback (§8). `/etc/hostid` stays, and the + module says so before it leaves (`zfs_config`): it is no resource the node-engine removes, and removing it would + change the node's hostid, so that the pool's next import could need `zpool import -f` (ADR 0679 §15). ## How it is checked -31. **Unit tests**, table-driven, one test per area, within the module's 500: no values gives no `zpool` or `zfs` - write but the due scrub; each convergence plan from parsed `zpool status` and `zfs get` output (an add, a kernel - name to its stable name, a removal, an empty list removing nothing, a log removal refused while not healthy, a - `log-mirror` change, a wait during a scrub); every refused form (a newline, quote, `$`, backtick or semicolon in - each field; a parameter or property not on its list; a `sharenfs` value; `-f`; a device with a signature or another - pool's label; a hostid of the wrong form or a label of another id); the call-site test of §19; the lock (a second - apply waits, a run with the lock held does nothing); the apply started only by `config-changed`, never a timer; - one scheduled resource; both ARC writes read back; applying from the last config file with the bus down; the - three templates (config file, options file, `zed.rc`); pruning never removes a ZFS snapshot whose name, property - or ledger entry does not fit, nor one with a hold or clone, and removes every surplus in one run; no ZFS snapshot - taken without a ledger record; `snapshots` back to `none` removes nothing; `zfs_snapshot` refuses a `mesh-` +31. **Unit tests**, table-driven, one test per area, within the module's 500: no values gives no `zpool` or `zfs` write + but the due scrub; each convergence plan from parsed `zpool status` and `zfs get` output (an add, a kernel name to + its stable name, a removal, an empty list removing nothing, a log removal refused while not healthy, a `log-mirror` + change, a wait during a scrub); every refused form (a newline, quote, `$`, backtick or semicolon in each field; a + parameter or property not on its list; a `sharenfs` value; `-f`; a device with a signature or another pool's label; + a hostid of the wrong form, a label of another id or one that cannot be read, and a hostid file holding another + value than the set one, each unhealthy and healthy again once the label and the file agree or `hostid` is unset); + the call-site test of §19, refusing any other `zgenhostid` or `zdb` form and a `zgenhostid` value not validated; the + lock (a second apply waits, a run with the lock held does nothing); the apply started only by `config-changed`, + never a timer; one scheduled resource; both ARC writes read back; applying from the last config file with the bus + down; the three templates (config file, options file, `zed.rc`); pruning never removes a ZFS snapshot whose name, + property or ledger entry does not fit, nor one with a hold or clone, and removes every surplus in one run; no ZFS + snapshot taken without a ledger record; `snapshots` back to `none` removes nothing; `zfs_snapshot` refuses a `mesh-` name; a scheduled `snapshot.taken.schedule` does not wake a person's waiter; a parameter awaiting a load is a - warning; the `.pacnew` warning; each change emits its event with before and after; one test per tool. The module - adds no integration test; §5 is the milestone's, and the main file's live tests stand for the module whole, said - in the pull request. + warning; the `.pacnew` warning; each change emits its event with before and after; one test per tool; no resource or + template of the manifest for `/etc/hostid`; the hostid converged at the apply's start after `zfs-import.target`; the + leave keeps `/etc/hostid` and says so. The module adds no integration test; §5 is the milestone's, and the main + file's live tests stand for the module whole, said in the pull request. diff --git a/03-DESIGN/01-to-be/42-the-machines-modules-in-order.md b/03-DESIGN/01-to-be/42-the-machines-modules-in-order.md index 5e832053..9aece7a6 100644 --- a/03-DESIGN/01-to-be/42-the-machines-modules-in-order.md +++ b/03-DESIGN/01-to-be/42-the-machines-modules-in-order.md @@ -170,7 +170,8 @@ named ZFS snapshot, a scrub's start, pause and stop. the states of ZFS's import, mount, share, volume and target units and of the distribution's scrub and trim timers; and, for the one pool its config value `pool` names, that pool's cache and log devices, its properties and its datasets' properties from fixed lists. The node-engine's composer refuses a second module owning one of its paths - (ADR 0593 §7, ADR 0051 §9). + (ADR 0593 §7, ADR 0051 §9), all but `/etc/hostid`, which is no resource: the module's apply reads it back instead + (ADR 0679 §1, §17). - **What it never writes** (ADR 0679 §1, §2): the package's own `/etc/default/zfs` and `/etc/zfs/zed.d` with its `zed.rc`, and what ZFS writes itself; it reads and shows them. A dataset's `sharenfs` is the seat `node-nfs-server`'s, `sharesmb` the SMB module's; the pool's files are the operator's (ADR 0051); the weekly @@ -178,10 +179,11 @@ named ZFS snapshot, a scrub's start, pause and stop. - **An unset or empty value changes nothing** (ADR 0679 §3): every new config value is "not managed" until the operator sets it through mesh-config, on the Approve for a trusted value (ADR 0348 §4, §8). Placing the new version on a node runs no `zpool` or `zfs` write but the scrub its schedule already runs, and places none of its new files. -- **Who applies** (ADR 0679 §9): the node-engine places the packages, files and units as the module's resources, - some only while a value holds; the module's root process `zfs-tools apply` converges the pool's devices and - properties at its start and on `config-changed`, never on a timer; the module's one scheduled run, under the same - lock, starts the scrub and the trim when due and takes and removes the scheduled ZFS snapshots (ADR 0679 §8). +- **Who applies** (ADR 0679 §9, §17): the node-engine places the packages, files and units as the module's resources, + some only while a value holds, all but `/etc/hostid`; the module's root process `zfs-tools apply` converges the pool's + devices and properties at its start and on `config-changed`, never on a timer, and writes `/etc/hostid` with ZFS's own + writer only while `hostid` is set and the pool's label agrees; the module's one scheduled run, under the same lock, + starts the scrub and the trim when due and takes and removes the scheduled ZFS snapshots (ADR 0679 §8). - **What it says** (ADR 0679 §10, §11, §12): every change, refusal and wait is an event, each kind on a subject of its own, on an events stream asked for by template; the last change per value, the schedule's pause and every scheduled ZFS snapshot are kept on the bus in its own states and ledger (ADR 0595). Its health names a refusal or a @@ -190,7 +192,8 @@ named ZFS snapshot, a scrub's start, pause and stop. - **What it never does** (ADR 0679 §7): it converges no data device, spare, special or dedup device, upgrades no pool, destroys no dataset, rolls back, renames and clears nothing; each is an act of its own, decided separately. - **When it leaves** (ADR 0679 §15): ZFS keeps running (the import, mount and ZFS target are never stopped), the - packages stay, its own files are removed and the distribution's timers are put back as found. + packages stay, its own files are removed but `/etc/hostid`, which stays and is said, and the distribution's timers + are put back as found. - **Its prerequisites** (ADR 0679 §16): three node-engine capabilities, built first in the same milestone under issue 1979, with their readers in mesh-sdk and the manifest validator. @@ -200,7 +203,7 @@ flowchart LR config -->|the module's config file| engine[the node-engine] engine -->|packages, files, units| node[ZFS on the node] engine -->|restarts on its config file| apply[zfs-tools apply, root] - apply -->|zpool add, remove, set; zfs set, inherit| node + apply -->|zpool add, remove, set; zfs set, inherit; zgenhostid| node sched[the scheduled run] -->|scrub, trim, ZFS snapshots and their removal| node follower[the event follower] -->|scrub ended, device appeared: start| apply apply -->|config.applied, refused, waiting| stream[(events stream)] -- 2.54.0 From 435fe73a0fad55982453cde8be80c04109fb0beb Mon Sep 17 00:00:00 2001 From: jochens Date: Fri, 13 Nov 2026 00:04:41 +0100 Subject: [PATCH 2/5] Design 42 zfs-owns-zfs: the lead's answers to the prepare's 24 questions, each against the principles --- .../zfs-owns-zfs-lead-answers.md | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md diff --git a/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md b/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md new file mode 100644 index 00000000..5dcf27f8 --- /dev/null +++ b/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md @@ -0,0 +1,86 @@ +--- +layer: to-be +status: in-progress +design: 42 +milestone: zfs-owns-zfs +updated: 2026-11-13 +decisions: + - "ADR 0679" +--- +# 42, milestone zfs-owns-zfs — the lead's answers to the prepare's questions + +The lead's answers to the prepare's design questions (Q-n) and to the places where a design line and the code +disagree (C-n), for the milestone part [zfs-owns-zfs](zfs-owns-zfs.md): each one line, naming the principle that +settles it (`00-META/principles.md`), cited as "design 42 zfs-owns-zfs A-n". The code read is the prepare's, at the +`origin/main` commits its milestone file names. + +- **A-1** (Q-1, §8; principles 2 and 7) The pool's name is not held by mesh-config: it is the zfs module's + `values` in the home server's assignment (seat `mesh-module-assigner`), a layer mesh-config's rename does not move. + So the module keeps `renamed-from: scrub-pool` for the values mesh-config holds, and at the delivery the lead moves + the assignment's value: `pool` set to that name through mesh-config for the home server, and the assignment + proposed without `scrub-pool` through `mesh-module-assigner.propose`, both before the new version is placed. +- **A-2** (Q-2, §14; principle 7) The module's ZED folder also holds the package's `zed-functions.sh`, from the + module's files archive, root's, mode 0644, under `if-config: [zed=on]` beside `zed.rc`; the handlers find it where + ZED points them, and nothing else changes. +- **A-3** (Q-3, §13; principles 2 and 7) `trim-schedule: none` is a set value meaning "no trim by the mesh": the + distribution's trim timers are held stopped for `none`, `weekly` and `monthly` alike; only an unset value leaves + them as found. +- **A-4** (Q-4, §3; principle 3) The validator refuses a `:` in a `config-lines` prefix, beside `}`, `$` and a + newline, naming the key. +- **A-5** (Q-5, §3; principle 3) The validator refuses `mib-bytes` on a value whose type is not a number, and a + `config-lines` key the module does not declare, as it refuses `${config:}` of an undeclared key today. +- **A-6** (Q-6, §18, §24; principles 1 and 6) The follower's process bus declares + `invokes: ["seat:node-service-manager.start"]`, and the module's `invokes` carries the same for its tools bundle. +- **A-7** (Q-7, §14, §18; principle 7) `/etc/zfs/mesh-zed.d` is a directory resource under `if-config: [zed=on]` + with `unknown: module`; `/run/zfs-tools` is a directory resource with `unknown: program`, as `/run/zfs-events` is. +- **A-8** (Q-8, §18; principle 3) `zfs-tools apply` exits 0 on a refusal and on a wait, which it says by event and + in its state `applied` and which make the module unhealthy by §29; it exits non-zero only when a command it ran + failed, so the node-engine gates the module on a real failure. +- **A-9** (Q-9, §30; principle 7) When the module leaves a node, its kept data (the states `applied`, `schedule` and + `findings`, the ledger `snapshots`, the events stream) is kept as every module's kept data is on leaving; a return + finds its scheduled ZFS snapshots' records. +- **A-10** (Q-10, §27; principle 7) The findings stream is the one design 47 G §383 defines for every observer: + `zfs-findings`, its events `finding-written.*`, `finding-cleared.*` and `findings-stated.*`, kept 7 days and + 16 MiB, said by the writer generated from the seat `mesh-conditions`' definition; the module declares it as §383 + says and builds nothing of its own for it. +- **A-11** (Q-11, acceptance test 8; principles 5 and 7) Test 8 runs in the test lab, on a pool built on a + file-backed device, never on the home server's pool. +- **A-12** (Q-12, §24; principles 3 and 4) A hand act's tool waits at most 30 seconds for the act's event; past it, + it answers "started", naming the act and that `zfs_module_events` reads its outcome, and never answers "done" + for what it did not see end. +- **A-13** (C-1, §4; principle 7) The node-engine states the new reading as `word:resources.if-config` and + `form:config-lines` (and `form:config-json`, A-15), computed by `ManifestReads` and marked by `ManifestNeeds`; + stopping at the first failure is stated by no capability, since the node-engine build that reads those words is + the build that stops. +- **A-14** (C-2, §11; ADR 0679 §3; principle 7) The validator accepts a config value with neither a default nor + `required` as "not managed until set"; built in the validator's subtasks of this milestone. +- **A-15** (C-3, §9; principles 2 and 7) The config file's content is one new node-engine placeholder + `${config-json}`: the module's set config values as one JSON object, an unset value absent, lists and objects as + JSON; no unset value refuses the module. It is built with §2 and §3 in the node-engine, the validator and + mesh-sdk's form list, and stated as `form:config-json`; no existing form writes an unset value as absent. +- **A-16** (C-4, §18; principle 7) The follower, which runs from boot, starts the apply unit once at its own start + and on the events §27 names; the apply's own wait for an unimported pool (§18) stands for the order after + `zfs-import.target`. No new process field. +- **A-17** (C-5, §24; principle 7) A hand act writes its act into the state `schedule` under its own key and starts + `zfs-mesh-run.service`; the run reads the key, acts under the same lock and guards, and deletes it. No instance + units. +- **A-18** (C-6, §24; principle 7) `node-service-manager.start` is called with `{scope, unit}`; the tool keeps + `why` in its own event. The seat is not changed. +- **A-19** (C-7, §26; principle 7) The ledger `snapshots` declares a fixed `max-mib` sized from the bound of 168 per + kind (§11); a full ledger takes §21's "ledger full" path. +- **A-20** (C-8, §21, §22, §26; principles 1 and 7) A process cannot write a ledger: the ledger is served to a tools + bundle alone, through the tool runner (mesh-sdk `buscalls`, `ProcessBus` has no ledger). The scheduled run records + `taken` and `removed` by calling its own module's tool `zfs_snapshots_record` (declared in the run's process bus + `invokes`), whose bundle applies the operation to the ledger; the tool refuses a snapshot not named `mesh-`. No new + field in mesh-sdk. +- **A-21** (C-9, §13; principle 2) When one record of a unit goes while another still declares it, the found state + passes to the record that stays, as a file is handed to the resource still declaring its path (ADR 0223); built in + the node-engine's §2 subtask. +- **A-22** (C-10, the test budget; the test-budget instruction) The node-engine's repository is over its budget (about 1,742 unit tests + against 500): each new table test merges or replaces at least as many tests in the file it touches, named in the + build map, so the count does not rise. +- **A-23** (C-11, §9, §11; principle 6) The config file carries `"trusted": false`; each value's own `trusted` (§11) + decides who sets it. +- **A-24** (C-12, §2, §3; principle 3) `config-lines` and `config-json` are added to the validator's and the + composer's placeholder tables, and the validator counts `if-config`, `config-lines` and `config-json` as placing + their keys. -- 2.54.0 From 8c98c27a5ebc5972bb183fce664c96da79e6df5a Mon Sep 17 00:00:00 2001 From: jochens Date: Fri, 13 Nov 2026 00:09:44 +0100 Subject: [PATCH 3/5] Design 42 zfs-owns-zfs: A-25, the form search finds ${config-json} --- 03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md b/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md index 5dcf27f8..752ee18b 100644 --- a/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md +++ b/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md @@ -84,3 +84,6 @@ settles it (`00-META/principles.md`), cited as "design 42 zfs-owns-zfs A-n". The - **A-24** (C-12, §2, §3; principle 3) `config-lines` and `config-json` are added to the validator's and the composer's placeholder tables, and the validator counts `if-config`, `config-lines` and `config-json` as placing their keys. +- **A-25** (A-15, S2; principle 3) `${config-json}` holds no colon, so the form search that finds `${
:` does not + find it: the manifest's reading also finds the exact token `${config-json}`, and a manifest that holds it needs + `form:config-json`, so no node-engine that cannot write it is given the module. -- 2.54.0 From 2c129789ffe165f15a9397282178efae0274f892 Mon Sep 17 00:00:00 2001 From: jochens Date: Fri, 13 Nov 2026 00:19:30 +0100 Subject: [PATCH 4/5] Design 42 zfs-owns-zfs: A-26, a module declares what another resource needs before it --- .../01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md b/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md index 752ee18b..03e52c45 100644 --- a/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md +++ b/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md @@ -87,3 +87,8 @@ settles it (`00-META/principles.md`), cited as "design 42 zfs-owns-zfs A-n". The - **A-25** (A-15, S2; principle 3) `${config-json}` holds no colon, so the form search that finds `${:` does not find it: the manifest's reading also finds the exact token `${config-json}`, and a manifest that holds it needs `form:config-json`, so no node-engine that cannot write it is given the module. +- **A-26** (§1, met in develop; principles 3 and 7) §1 stands: a module declares a resource another of its resources + needs before that one, since the apply now stops at the first failure. The pacman module declares its package + before its config file, and its package fails while the config file is missing, so the stop would keep a node + from restoring its package manager: in this milestone the pacman module's config file moves before its package, + and the node-engine's probe test of that restore keeps the pacman module's own resource names, in that order. -- 2.54.0 From 4cb9efadae248fc353eb7d33c94d7fcd4d99478b Mon Sep 17 00:00:00 2001 From: jochens Date: Fri, 13 Nov 2026 00:28:08 +0100 Subject: [PATCH 5/5] Design 42 zfs-owns-zfs: A-27 to A-29, met in develop --- .../01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md b/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md index 03e52c45..c8d90802 100644 --- a/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md +++ b/03-DESIGN/01-to-be/42-milestones/zfs-owns-zfs-lead-answers.md @@ -92,3 +92,9 @@ settles it (`00-META/principles.md`), cited as "design 42 zfs-owns-zfs A-n". The before its config file, and its package fails while the config file is missing, so the stop would keep a node from restoring its package manager: in this milestone the pacman module's config file moves before its package, and the node-engine's probe test of that restore keeps the pacman module's own resource names, in that order. +- **A-27** (§11, met in develop; principle 7) `snapshots` is an object, so its `none` is the object holding only the + key `none` set to true; keep counts are its other form, and the text `none` is refused as the type refuses it. +- **A-28** (§11, met in develop; principle 3) One refused value refuses the whole config: nothing is converged until + every value is valid, and each refused value is its own `config.refused`. +- **A-29** (§11, §18, met in develop; principle 3) The node's memory is read by the apply and given to the parse; a + memory that cannot be read refuses `arc-max` and `arc-min`, never guesses them. -- 2.54.0