Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c231102f8 |
@@ -131,32 +131,6 @@ the plan says it too.
|
||||
| Genesis raises the forge as its module declares it | a genesis test that raises, assigns, and finds the module holding rather than raising a second |
|
||||
| Live | the next cutover on an adopted machine: `take` shows the comparison, refuses the downgrade if there is one, and the service keeps its configuration and its secret |
|
||||
|
||||
## Built, 2026-10-02
|
||||
|
||||
> **Progressive insight — 2026-10-02.** The decision stands; these are the facts of its building.
|
||||
|
||||
Built across mesh-host 63 and 64 and mesh-controller 201, 202 and the pull request that followed
|
||||
them. Rule 1: `take` previews every held thing's comparison and ends with a digest; `take --yes
|
||||
<digest>` acts on exactly that preview, and a changed preview or an account older than the flip
|
||||
allows is refused, as the flip's are. A published port's reach is said as the machine reported it,
|
||||
behind the found firewall whose rules are not read. Rule 2: an older image, a differing file and a
|
||||
minted, unaccepted secret for found data refuse, overridden by `--downgrade`, `--replace <path>` and
|
||||
`--mint <name>`; the secrets a module holds on a machine are read with where each came from. Rule 3:
|
||||
`secret accept --provider` reaches a required secret. Rule 4: the per-machine setting is `networks`,
|
||||
a container id to the found networks it keeps; judged for an adopted machine only, joined by the host
|
||||
after the container runs, part of the container's spec, named in the preview. Rule 5: the host's
|
||||
facts, former targets and strays. Rule 6: one judgement, run where a setting is stored and where a
|
||||
machine is composed; a module whose stored setting its definition can no longer compose is left out
|
||||
of the declaration, the envelope says so, the host keeps that module's things, and `plan` and `push`
|
||||
say it by name. A key that reaches nothing is refused where stored and said by `plan`, and never
|
||||
costs a module. Rule 7: genesis raises the forge under the module's container name, with its image
|
||||
digest and its data directory; the network is the one difference left, said by the take, because the
|
||||
bootstrap forge reaches the store on the machine's loopback.
|
||||
|
||||
**Not yet proven live.** Every machine of this mesh is converged, so the table's last row — a take
|
||||
on an adopted machine — waits for the next adoption. What is live is what the rows above it check.
|
||||
Issues 086, 098, 099, 100 and 101 stay located until that row is read.
|
||||
|
||||
## References
|
||||
|
||||
- [ADR 0100](0100-a-node-in-use-is-adopted-before-it-is-converged.md), [ADR 0102](0102-the-mesh-writes-into-a-shared-file-never-over-it.md), [ADR 0103](0103-what-an-adopted-node-holds-and-what-its-guard-refuses.md), [ADR 0104](0104-a-provision-may-be-answered-by-an-adapter-to-the-predecessor.md), [ADR 0162](0162-a-merge-produces-a-tiered-plan-the-mesh-keeps.md)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-host]
|
||||
updated: 2026-10-02
|
||||
updated: 2026-10-01
|
||||
decisions:
|
||||
- 02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md
|
||||
- 02-DECISIONS/0141-the-host-delivers-its-own-successor.md
|
||||
@@ -163,19 +163,6 @@ a resource's former targets, removes a container or file it wrote under a name t
|
||||
longer names, never removes what was found, and reports what runs on the machine that it neither
|
||||
wrote nor holds. *How it is checked:* ADR 0163's table.
|
||||
|
||||
**What the host joins, keeps and raises for a take** — revision, 2026-10-02
|
||||
([ADR 0163](../../02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md), rules 4, 6 and 7). A
|
||||
container may name networks it also joins once it runs — the found network a per-machine setting keeps
|
||||
for a taken container while a neighbour still resolves it there; joined after the run, part of the
|
||||
container's spec, refused when it cannot be joined. A declaration may name the modules the mesh left
|
||||
out of it because a stored setting cannot compose with the module's definition: the host keeps what it
|
||||
wrote and holds for a left-out module and says so, where absence used to read as removal. And genesis
|
||||
raises the bootstrap forge under the forge module's container name, with the module's image digest and
|
||||
its data directory, so the module holds it by the found rule; the network is the one difference a take
|
||||
has left to say. *How it is checked:* a host test joins a kept network and refuses one it cannot; a
|
||||
host test keeps a left-out module's record and hold and removes an absent module's; a bootstrap test
|
||||
holds the installer's constants to the module's manifest where the catalogue is checked out beside it.
|
||||
|
||||
**Found reaches every kind that can touch what the machine has**
|
||||
([ADR 0103](../../02-DECISIONS/0103-what-an-adopted-node-holds-and-what-its-guard-refuses.md)). For a module not yet taken, a directory present with no record
|
||||
keeps its mode and owner, a unit present with no record keeps its state and boot setting, a
|
||||
|
||||
@@ -8,7 +8,7 @@ code:
|
||||
- mesh-host packaging/nox-mesh-host-network.sh
|
||||
- mesh-controller internal/token
|
||||
- mesh-controller internal/inventory/nodes.go
|
||||
updated: 2026-10-02
|
||||
updated: 2026-10-01
|
||||
decisions:
|
||||
- 02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md
|
||||
- 02-DECISIONS/0100-a-node-in-use-is-adopted-before-it-is-converged.md
|
||||
@@ -323,21 +323,6 @@ network are said. `take --yes <digest>` cuts over what was previewed, as the fli
|
||||
container may keep a found network by a per-machine setting while its neighbours are not yet taken.
|
||||
*How it is checked:* ADR 0163's table.
|
||||
|
||||
**A setting is judged where it is stored, and the take's words** — revision, 2026-10-02
|
||||
([ADR 0163](../../02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md), rules 1, 2, 4 and 6).
|
||||
The preview ends with a digest of what it said; `take --yes <digest>` acts on that preview and nothing
|
||||
else, and a preview that has changed since, or an account of the machine older than the flip allows, is
|
||||
refused as the flip's is. A module the machine holds nothing for has nothing to compare, and `--yes`
|
||||
suffices. The overrides are `--downgrade`, `--replace <path>` and `--mint <name>`; the per-machine
|
||||
setting that keeps a found network is `networks`, a container id to the networks it keeps, accepted
|
||||
for an adopted machine only. Storing a setting composes it against the module's current definition and
|
||||
refuses, naming node, module, layer and key, what cannot compose or reaches nothing. A definition that
|
||||
later moves under a stored setting costs that module its place in the machine's declaration, said by
|
||||
name in `plan`, `push` and the declaration itself, and the machine is told everything else; a stray
|
||||
setting no longer refuses the machine where it is read. *How it is checked:* controller tests over the
|
||||
one judgement — refused where stored, a module left out where composed, the envelope naming it — and
|
||||
over a take's digest, staleness and secrets.
|
||||
|
||||
A candidate machine is not empty. It has a package manager, probably a container runtime,
|
||||
configuration somebody chose. [ADR 0005](../../02-DECISIONS/0005-the-node-host.md)
|
||||
says the host never touches what it did not create — adoption is the deliberate act of taking
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: proposed
|
||||
code: []
|
||||
updated: 2026-09-27
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-controller internal/inventory
|
||||
- mesh-controller internal/catalogue
|
||||
- mesh-controller cmd/mesh-controller
|
||||
updated: 2026-10-01
|
||||
decisions:
|
||||
- 02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md
|
||||
- 02-DECISIONS/0120-a-roster-fact-carries-its-format-as-a-template.md
|
||||
@@ -14,10 +17,10 @@ decisions:
|
||||
# 29 — A node has operator accounts, and the mesh owns what lives under a home
|
||||
|
||||
**The mesh models machines but not the people on them.** A node record holds its name, its
|
||||
address, its mode — and nothing about *who a person is* on it: `jochens` on novox, `ace` on ace,
|
||||
`jochen` on shanks and g14. That username is not incidental. It decides who a file under `~` is
|
||||
owned by, who a user service runs as, and — the case that surfaced this — which account `ssh
|
||||
<node>` logs in as. The predecessor knew it (its per-node `user:`, and the modules that wrote a
|
||||
address, its mode — and nothing about *who a person is* on it: one login name on the build node,
|
||||
another on the home-server, a third on both workstations. That username is not incidental. It
|
||||
decides who a file under `~` is owned by, who a user service runs as, and — the case that surfaced
|
||||
this — which account `ssh <node>` logs in as. The predecessor knew it (its per-node `user:`, and the modules that wrote a
|
||||
person's `~/.ssh/config`, `~/.zshrc`, `~/.config`); the mesh, taking those over, kept the machine
|
||||
facts and dropped the human one.
|
||||
|
||||
@@ -28,8 +31,9 @@ Several things are missing, and they are one idea.
|
||||
A node has one or more **operator accounts**: the human logins on it. At minimum a name; the
|
||||
mesh already knows the node and its address, so `<account>@<node>` is then a complete answer to
|
||||
"who am I, where." It is the mesh's to hold because everything below is derived from it, and
|
||||
because it is exactly the fact that was silently lost — `ssh ace` failed to `ace` because nothing
|
||||
in the mesh said ace's account is `ace`.
|
||||
because it is exactly the fact that was silently lost — `ssh home-server` logged in under the
|
||||
workstation's own name, because nothing in the mesh said the home-server's account is a different
|
||||
one.
|
||||
|
||||
## 2. A resource may live under a home, owned by its account
|
||||
|
||||
@@ -65,14 +69,14 @@ create `~/.ssh` at `0700`, chown it to the account, and own the files it places
|
||||
|
||||
**The boundary — and it is the reason this is safe:** `~/.ssh` is the one directory where a wrong
|
||||
declaration locks a person out of their own machine. So the mesh's *found-vs-owned* semantics
|
||||
([ADR 0126](../../02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md),
|
||||
([ADR 0118](../../02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md),
|
||||
adoption) apply *inside* the home directory. The mesh **owns** the directory and the files above; it
|
||||
**holds as found — never rewrites, never removes** — the operator's own contents: their **private
|
||||
keys** and their **personal drop-ins** (`config.d/personal`, the personal `Host` aliases a
|
||||
workstation carries, exactly as `hosts.local` is the home the mesh never rewrites for `/etc/hosts`).
|
||||
Reconcile removing an unassigned `config.d/mesh` is fine; the same logic aimed at `id_ed25519` or an
|
||||
operator's own `authorized_keys` entry is a lockout. This is the login-channel cousin of the rule
|
||||
[ADR 0125](../../02-DECISIONS/0117-a-machines-uplink-is-a-seat.md) draws for the uplink and the sshd
|
||||
[ADR 0117](../../02-DECISIONS/0117-a-machines-uplink-is-a-seat.md) draws for the uplink and the sshd
|
||||
module draws for the firewall: **the mesh must never be able to arrange the one failure that severs
|
||||
its own way back in.** The carve-out is not a convenience; it is that rule, in `~/.ssh`.
|
||||
|
||||
@@ -108,12 +112,12 @@ found-vs-owned boundary of §3 is exactly what guarantees nothing already there
|
||||
|
||||
None of this needs a node to discover the mesh, and none of it needs a control-plane module of its
|
||||
own. The ssh files are **roster facts**
|
||||
([ADR 0128](../../02-DECISIONS/0120-a-roster-fact-carries-its-format-as-a-template.md)): once the
|
||||
([ADR 0120](../../02-DECISIONS/0120-a-roster-fact-carries-its-format-as-a-template.md)): once the
|
||||
roster view carries a node's **host key** and its **account** beside its name and address, the
|
||||
`ssh-client` module ships a template for `known_hosts`, `config` and `authorized_keys`, and the
|
||||
controller renders each node's copy from the full roster and pushes it. The mesh owns the data; the
|
||||
module owns ssh's format; the control plane gains no ssh syntax. It is the same act as composing a
|
||||
peer list or `/etc/hosts` — which is why there is **no novox-only "mesh-ssh" module**: the
|
||||
peer list or `/etc/hosts` — which is why there is **no control-node-only "mesh-ssh" module**: the
|
||||
centralization is the controller's composition, not a module that runs somewhere. Only non-secret
|
||||
facts travel (names, addresses, accounts, host keys, the CA public key); the private key stays the
|
||||
operator's, placed as an operator-owned file, referenced by path.
|
||||
@@ -129,6 +133,44 @@ operator's, placed as an operator-owned file, referenced by path.
|
||||
They meet at the account and the CA, not at a bespoke module. The `sshd` server side already exists;
|
||||
the client/identity side and the CA are the open pieces.
|
||||
|
||||
## What has shipped, and what has not
|
||||
|
||||
*Recorded 2026-10-01 from the controller's main branch, not from intent.*
|
||||
|
||||
**Built (mesh-controller, merged 2026-09-27):**
|
||||
|
||||
- **§1, the account as a node fact.** A node record carries an operator account and, optionally,
|
||||
its home. Empty is a real state — a freshly enrolled or headless machine has no operator account
|
||||
known yet — and an empty home means *derive it* (the superuser's home for the superuser, the
|
||||
conventional per-user home otherwise), so the common case needs no entry. The controller's node
|
||||
command sets it. One account per node is what exists; "one or several" below is still open.
|
||||
- **§2, resources under a home.** The account and its home are offered as machine facts, and a
|
||||
resource's *path and owner* resolve placeholders exactly as its content does — so a module places
|
||||
a file under a person's home, owned by that person, naming neither. A roster file may say it lives
|
||||
under the home: it is rendered per node, placed under that node's account's home, chowned to the
|
||||
account, and a node with no account gets none.
|
||||
- **§5, the composed ssh config.** The roster rendering carries each node's account, so the
|
||||
`ssh-client` template can emit a `Host` block per node with the right login name. Composed
|
||||
end-to-end in the controller's tests.
|
||||
|
||||
**Written but not shipped:** the `ssh-client` catalogue module itself exists on a branch of the
|
||||
module repository; its pull request was closed with a hold until this design is deployed, and
|
||||
nothing has deployed it since. The predecessor's generator still writes every workstation's ssh
|
||||
client blocks today — which is where [issue 172](../../04-ISSUES/172-the-ssh-client-block-matches-one-spelling-of-a-machine/00-report.md)
|
||||
was found.
|
||||
|
||||
**Not built:** the SSH CA and certificates (§4), `known_hosts` and `authorized_keys` as roster files,
|
||||
the found-vs-owned boundary inside `~/.ssh` (§3 — the controller has no rule yet that refuses to
|
||||
rewrite a private key), adoption of existing keys, the ssh-agent as a user service, and user-scoped
|
||||
services in general. The host vocabulary still has no user-scope unit at all; a workstation's
|
||||
per-user daemons (a bar watchdog, a config reloader, an audio service masked per user) have no form
|
||||
the mesh can send.
|
||||
|
||||
**A gap this surfaced:** §1 shipped as code before it had a decision record. The account as a node
|
||||
fact, the home as a placement root, and what the mesh may and may not do under a home are each a
|
||||
decision this document names but no record states. They are the next records to write, before the
|
||||
family of §2 modules is built.
|
||||
|
||||
## Why now, and why not yet
|
||||
|
||||
**Why it matters:** when HAL retires, the generators that keep `~/.ssh`, shell config and the
|
||||
@@ -137,7 +179,7 @@ alias and its trust, and a fresh machine has no operator dotfiles at all — the
|
||||
service and leave the human unable to work on the box.
|
||||
|
||||
**Why not build it reflexively:** it is a real addition to the node model, the resource model, and
|
||||
the seat set, and must be gotten right. The mechanism half is now settled — ADR 0128 is what lets
|
||||
the seat set, and must be gotten right. The mechanism half is now settled — ADR 0120 is what lets
|
||||
the ssh files be templates with no control-plane format — so what remains to decide here is the
|
||||
model:
|
||||
|
||||
@@ -156,15 +198,18 @@ model:
|
||||
unnecessary, and forwarding an agent into a node exposes the operator's keys to that node's root —
|
||||
so prefer certificates and `ProxyJump` over forwarding.
|
||||
|
||||
**Not urgent, not blocking.** ssh and dotfiles work today because HAL's generators still run as the
|
||||
substrate. This becomes load-bearing in the node-by-node retirement phase, not before — which is the
|
||||
right time to build it, once the account and CA model are decided here.
|
||||
**Now load-bearing.** The migration of every node to the mesh is complete; what remains of the
|
||||
predecessor is exactly the user environment this design covers — ssh config, dotfiles, the desktop
|
||||
stack and the per-user services of the two workstations. Those generators are the last thing
|
||||
keeping the predecessor running, so the model questions above are no longer deferred: the account
|
||||
record, the home as a placement root, user-scoped services and the one-off steps a hook used to run
|
||||
each need a decision before the modules that replace the generators can be written.
|
||||
|
||||
## References
|
||||
|
||||
- The gap was found generating `~/.ssh/config` from the *HAL* registry (`hal/terminal`'s
|
||||
postConfigure hook), which the nox mesh has no equivalent for.
|
||||
- [ADR 0128](../../02-DECISIONS/0120-a-roster-fact-carries-its-format-as-a-template.md) — the roster
|
||||
- [ADR 0120](../../02-DECISIONS/0120-a-roster-fact-carries-its-format-as-a-template.md) — the roster
|
||||
fact mechanism that renders the ssh files, format owned by the module.
|
||||
- [ADR 0112](../../02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md) — the
|
||||
system-path placement this mirrors for home paths.
|
||||
@@ -173,6 +218,6 @@ right time to build it, once the account and CA model are decided here.
|
||||
- [ADR 0113](../../02-DECISIONS/0113-the-vault-makes-every-secret.md) — the CA key is a secret the
|
||||
vault makes; [ADR 0114](../../02-DECISIONS/0114-a-shared-credential-rotates-over-two-credentials.md)
|
||||
— short-lived certs as rotation.
|
||||
- [ADR 0125](../../02-DECISIONS/0117-a-machines-uplink-is-a-seat.md),
|
||||
[ADR 0126](../../02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md) —
|
||||
- [ADR 0117](../../02-DECISIONS/0117-a-machines-uplink-is-a-seat.md),
|
||||
[ADR 0118](../../02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md) —
|
||||
the never-sever-the-channel rule and the found-vs-owned semantics, applied here to `~/.ssh`.
|
||||
|
||||
@@ -38,7 +38,7 @@ document is written and this one's status becomes `implemented`.
|
||||
| [`26-the-seats.md`](26-the-seats.md) | **Proposed.** What a mesh can have one of, who fills each, and a seat's holder answering for the provision it delivers — including the `git` seat a build's source can live on | [ADR 0126](../../02-DECISIONS/0126-a-module-declares-its-own-seats.md) (superseding [ADR 0110](../../02-DECISIONS/0110-a-seat-is-a-module-assignment-from-a-closed-set.md)), [ADR 0111](../../02-DECISIONS/0111-a-build-source-is-on-the-git-seat-or-external.md), [ADR 0109](../../02-DECISIONS/0109-a-package-registry-seat-is-one-per-ecosystem.md) |
|
||||
| [`27-a-module-requires-the-mesh-resolves.md`](27-a-module-requires-the-mesh-resolves.md) | **Proposed.** One concept for everything a module needs: a requirement with a contract, answered by one of four kinds of provider, resolved at assignment or refused. Retires settings, placeholders, facts and paths in definitions | [ADR 0112](../../02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md), [ADR 0113](../../02-DECISIONS/0113-the-vault-makes-every-secret.md), [ADR 0114](../../02-DECISIONS/0114-a-shared-credential-rotates-over-two-credentials.md), [ADR 0126](../../02-DECISIONS/0126-a-module-declares-its-own-seats.md) (superseding [ADR 0110](../../02-DECISIONS/0110-a-seat-is-a-module-assignment-from-a-closed-set.md)) |
|
||||
| [`28-building-the-bus.md`](28-building-the-bus.md) | **Proposed.** The five steps of the bus work in the order their dependencies allow, each ending at a bed — with the surface measured, so no step's size is a guess | [ADR 0116](../../02-DECISIONS/0116-the-bus-is-built-in-five-steps.md), [ADR 0106](../../02-DECISIONS/0106-the-bus-is-nats.md), [ADR 0074](../../02-DECISIONS/0074-the-wire-is-specified-not-the-types.md) |
|
||||
| [`29-a-node-has-operator-accounts.md`](29-a-node-has-operator-accounts.md) | **Proposed.** The mesh models machines but not the humans on them: a node gains operator accounts, and a resource may live under a home owned by its account — what would own ~/.ssh, dotfiles and ~/.config when HAL retires | [ADR 0112](../../02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md), [ADR 0051](../../02-DECISIONS/0051-shared-data-is-the-operators.md) |
|
||||
| [`29-a-node-has-operator-accounts.md`](29-a-node-has-operator-accounts.md) | **In progress.** A node has an operator account and a resource may live under its home — built in the controller; the ssh-client module, the SSH CA, the `~/.ssh` boundary and user-scoped services are not. The account fact still wants its decision record | [ADR 0112](../../02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md), [ADR 0051](../../02-DECISIONS/0051-shared-data-is-the-operators.md) |
|
||||
|
||||
| [`32-what-a-module-declares.md`](32-what-a-module-declares.md) | **Proposed.** What a module declares and what the bus derives from it: three namespaces, subjects from local names, queues never declared, the five relationships, and the build-publish-deploy lifecycle on one bus | [ADR 0126](../../02-DECISIONS/0126-a-module-declares-its-own-seats.md), [ADR 0127](../../02-DECISIONS/0127-amqp-is-a-provision-not-the-bus.md), superseded by [ADR 0131](../../02-DECISIONS/0131-everything-on-the-mesh-speaks-to-the-broker-seat.md) (superseding [ADR 0125](../../02-DECISIONS/0125-the-bus-is-the-only-broker.md)), [ADR 0041](../../02-DECISIONS/0041-events-are-a-relationship.md) |
|
||||
|
||||
|
||||
@@ -40,9 +40,3 @@ it changes before it changes it, and for taking a module this one does not.
|
||||
|
||||
[ADR 0163](../../02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md), rules 1 and 2: the preview names a narrowing. Building follows,
|
||||
host first, then the controller's `take`.
|
||||
|
||||
## Built, 2026-10-02
|
||||
|
||||
mesh-controller 201 and the pull request after it: the preview names it, and `take --yes <digest>`
|
||||
acts on the preview that was read. Stays located until a take is read on an adopted machine — every
|
||||
machine of this mesh is converged today, so the record's live row has not been run.
|
||||
|
||||
-10
@@ -53,13 +53,3 @@ network, or it is not a takeover.
|
||||
|
||||
[ADR 0163](../../02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md), rule 7: genesis raises as the module declares. Building follows,
|
||||
host first, then the controller's `take`.
|
||||
|
||||
## Built in part, 2026-10-02
|
||||
|
||||
mesh-host 64: genesis raises the forge under the module's container name (`gitea`), pinned to the
|
||||
module's image digest, with the module's data directory mounted at `/data` — so the module finds it,
|
||||
holds it, and a take compares equal images and the same data. A test holds the installer's constants
|
||||
to the module's manifest where the catalogue is checked out beside it. The network is the difference
|
||||
left: the bootstrap forge runs on the machine's network to reach the store on its loopback, the module
|
||||
runs bridged and publishes its ports, and the take says so. Closing waits for group 9's genesis test —
|
||||
a mesh raised, the module assigned, and the module found holding rather than raising a second forge.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
status: resolved
|
||||
status: located
|
||||
opened: 2026-09-23
|
||||
located-in: [mesh-controller cmd/mesh-controller/adoption.go (take previews nothing), mesh-host internal/apply (the comparison and the record)]
|
||||
fixed-by: mesh-controller (the pull request after 201: JudgeSettings, LeftOut), mesh-host 64 (left_out kept)
|
||||
fixed-by:
|
||||
amended-design:
|
||||
---
|
||||
|
||||
@@ -63,12 +63,3 @@ knowing the code.
|
||||
|
||||
[ADR 0163](../../02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md), rule 6: judged where stored; an impossible statement costs a module. Building follows,
|
||||
host first, then the controller's `take`.
|
||||
|
||||
## Resolved, 2026-10-02
|
||||
|
||||
One judgement, in the catalogue, run where a setting is stored and where a machine is composed. Stored,
|
||||
a setting that cannot compose with the module's current definition is refused naming the node, the
|
||||
module, the layer and the key; a key that reaches nothing is refused there too. Composed, a definition
|
||||
that moved under a stored setting leaves that module out of the machine's declaration — the envelope
|
||||
names it, the host keeps what it holds and wrote for it, `plan` and `push` say it — and the machine is
|
||||
told everything else. A stray setting no longer refuses the whole machine where it is read.
|
||||
|
||||
+2
-10
@@ -1,8 +1,8 @@
|
||||
---
|
||||
status: resolved
|
||||
status: located
|
||||
opened: 2026-09-23
|
||||
located-in: [mesh-controller cmd/mesh-controller/adoption.go (take previews nothing), mesh-host internal/apply (the comparison and the record)]
|
||||
fixed-by: mesh-host 63 (former targets removed, strays reported), mesh-controller 201/202 (strays shown)
|
||||
fixed-by:
|
||||
amended-design:
|
||||
---
|
||||
|
||||
@@ -80,11 +80,3 @@ found, and so would be kept for ever on purpose.
|
||||
|
||||
[ADR 0163](../../02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md), rule 5: former targets are removed and strays reported. Building follows,
|
||||
host first, then the controller's `take`.
|
||||
|
||||
## Resolved, 2026-10-02
|
||||
|
||||
mesh-host 63: the host's record keeps a resource's former targets, removes a container or file it
|
||||
wrote under a name the declaration no longer names, never what was found, and reports strays — what
|
||||
runs on the machine that the mesh neither wrote nor holds. mesh-controller 201 and 202 show strays
|
||||
on `node show` for an adopted and a converged machine alike; the live mesh reported four on the
|
||||
control node the evening it rolled.
|
||||
|
||||
@@ -68,9 +68,3 @@ written.
|
||||
|
||||
[ADR 0163](../../02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md), rules 1 and 2: the difference is shown and a differing file refuses. Building follows,
|
||||
host first, then the controller's `take`.
|
||||
|
||||
## Built, 2026-10-02
|
||||
|
||||
mesh-host 63 reports the difference between the kept original and the declared content; mesh-controller
|
||||
201 shows it in the preview and refuses a differing file unless `--replace <path>` names it, or the
|
||||
module declares the file partially. Stays located until a take is read on an adopted machine.
|
||||
|
||||
@@ -65,9 +65,3 @@ expected rate.
|
||||
|
||||
[ADR 0163](../../02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md), rules 1 and 2: the images are compared by age and a downgrade refuses. Building follows,
|
||||
host first, then the controller's `take`.
|
||||
|
||||
## Built, 2026-10-02
|
||||
|
||||
mesh-host 63 reports the found image and both images' creation dates; mesh-controller 201 says
|
||||
DOWNGRADE and refuses unless `--downgrade` is said. Stays located until a take is read on an adopted
|
||||
machine.
|
||||
|
||||
@@ -70,11 +70,3 @@ the module can only be installed fresh.
|
||||
|
||||
[ADR 0163](../../02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md), rules 2 and 3: a minted secret for found data refuses; secret accept reaches required secrets. Building follows,
|
||||
host first, then the controller's `take`.
|
||||
|
||||
## Built, 2026-10-02
|
||||
|
||||
`secret accept <node> <module> <name> --provider <node>` reaches a required secret (mesh-controller 201).
|
||||
The pull request after it reads every secret a module holds on a machine with its origin, and a take
|
||||
of a module whose data was found refuses a minted, unaccepted one — naming the accept that carries
|
||||
the existing value in, or `--mint <name>` to let the service take the new one. Stays located until
|
||||
a take is read on an adopted machine.
|
||||
|
||||
-7
@@ -66,10 +66,3 @@ exercise.
|
||||
|
||||
[ADR 0163](../../02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md), rules 1 and 4: the neighbours are named; a found network may be kept by a setting. Building follows,
|
||||
host first, then the controller's `take`.
|
||||
|
||||
## Built, 2026-10-02
|
||||
|
||||
The preview names every neighbour on a found network (mesh-controller 201). The pull request after it
|
||||
adds the per-machine setting `networks` — a container id to the found networks it keeps — judged for an
|
||||
adopted machine only, and mesh-host 64 has the taken container join each once it runs. Stays located
|
||||
until a take is read on an adopted machine.
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
---
|
||||
status: resolved
|
||||
status: located
|
||||
opened: 2026-09-26
|
||||
located-in: [mesh-host internal/apply]
|
||||
fixed-by: mesh-host 63 (every written field compared), mesh-controller 201 (build says the policy)
|
||||
amended-design:
|
||||
---
|
||||
|
||||
# 126 — a volume path is not in the spec comparison, and a roll-out raced a data move
|
||||
@@ -52,9 +50,3 @@ the install-page junk was discarded twice.
|
||||
|
||||
[ADR 0163](../../02-DECISIONS/0163-taking-a-module-over-is-a-comparison.md), rules 5 and 7: every field compared; build says the policy. Building follows,
|
||||
host first, then the controller's `take`.
|
||||
|
||||
## Resolved, 2026-10-02
|
||||
|
||||
mesh-host 63: every field the host writes is compared before a container is called current, volumes
|
||||
and paths included. mesh-controller 201: `build` and the take-in say when a module's policy rolls a
|
||||
result out at once; under ADR 0162 the plan says it too.
|
||||
|
||||
Reference in New Issue
Block a user