diff --git a/README.md b/README.md index 33d7284..367f181 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ mesh-host profile ``` That is the whole installation. One statically linked binary, nothing else present, no runtime -to install first ([`novox/hq` ADR 0041](https://git.novox.be/novox/hq)). +to install first ([`novox/hq` ADR 0005](https://git.novox.be/novox/hq)). ## What it is for @@ -56,7 +56,7 @@ cannot be asked to: [firewall privileged] A declaration is JSON, versioned, and an **ordered list** of resources — the order is stated rather than derived, because deriving it would be the host deciding -([`novox/hq` ADR 0043](https://git.novox.be/novox/hq)). The vocabulary is `directory`, `file` +([`novox/hq` ADR 0005](https://git.novox.be/novox/hq)). The vocabulary is `directory`, `file` and `service`, and **anything outside it refuses the whole declaration**: a host that skipped what it did not understand would apply most of a declaration and report success. @@ -153,7 +153,7 @@ CGO_ENABLED=0 go build -ldflags="-s -w" -o mesh-host ./cmd/mesh-host Roughly 3 MB, static, no dynamic dependencies. Cross-compiles with `GOOS`/`GOARCH`; a host is built once per architecture and copied, never built on the machine it runs on. -**Mocking the boundary is forbidden** ([`novox/hq` ADR 0034](https://git.novox.be/novox/hq)). +**Mocking the boundary is forbidden** ([`novox/hq` ADR 0017](https://git.novox.be/novox/hq)). Every detector is exercised against a fake runner for its logic *and* against this machine for its behaviour. The tests do not assert which capabilities a machine has — that varies, and is the point of detecting — they assert that detection tells the truth about whatever is there. diff --git a/cmd/mesh-host/main.go b/cmd/mesh-host/main.go index 8e84528..3f4f9ae 100644 --- a/cmd/mesh-host/main.go +++ b/cmd/mesh-host/main.go @@ -31,7 +31,7 @@ import ( // version is stamped at build time. Unset in a development build, and said so rather than // defaulted to something that looks like a release. // builtFor names the operating system this host was built for, set at link time -// (novox/hq ADR 0060). A host built without one refuses to do anything that touches the +// (novox/hq ADR 0005). A host built without one refuses to do anything that touches the // machine, rather than guessing and calling a package manager that is not there. var builtFor = "" @@ -161,7 +161,7 @@ func run(ctx context.Context, command string, opts options) error { return fmt.Errorf("reading the declaration: %w", err) } // ParseTrusted: a file handed to the host by someone already running it as root is - // not the link. novox/hq ADR 0047 bounds what a REMOTE party may push; someone who + // not the link. novox/hq ADR 0005 bounds what a REMOTE party may push; someone who // can write this file and run this binary can do anything the binary can, so refusing // them an action would buy nothing and would make an action untestable except by // rebuilding the bundle. @@ -172,7 +172,7 @@ func run(ctx context.Context, command string, opts options) error { return runApply(ctx, opts, d, opts.file) case "reconcile": - // The first node's path. novox/hq ADR 0038: no mesh reachable means the declaration + // The first node's path. novox/hq ADR 0004: no mesh reachable means the declaration // comes from the bundle the host carries. There is no link yet, so this is currently // the only source — which is a stage, not a design, and saying so beats implying the // other source exists. @@ -275,7 +275,7 @@ func writeInventory(inv inventory.Inventory) { writeProfile(inv.Profile) // Printed last and never hidden. An inventory that quietly omits what it could not read - // is the same fault as a report assembled from intent (novox/hq ADR 0035). + // is the same fault as a report assembled from intent (novox/hq ADR 0018). if len(inv.Unreadable) > 0 { fmt.Println("\ncould not read:") for _, u := range inv.Unreadable { @@ -307,7 +307,7 @@ func runApply(ctx context.Context, opts options, d *declaration.Declaration, sou } // Refuse a declaration naming a shape this host cannot apply, before anything is applied. // An android host has no `package` applier, and finding that out half way through is the - // half-configured machine this host exists to prevent (novox/hq ADR 0060). + // half-configured machine this host exists to prevent (novox/hq ADR 0005). if err := system.Check(sys, d); err != nil { return err } @@ -336,7 +336,7 @@ func runApply(ctx context.Context, opts options, d *declaration.Declaration, sou } // Only now, and only after a clean apply: this version got as far as a completed - // reconcile, which is the whole of what "known good" claims (novox/hq ADR 0059). Not + // reconcile, which is the whole of what "known good" claims (novox/hq ADR 0005). Not // health — a disconnected node is ordinary, and a resource that fails is the machine's // problem rather than the binary's. // diff --git a/internal/apply/apply.go b/internal/apply/apply.go index 734c89d..3d564e7 100644 --- a/internal/apply/apply.go +++ b/internal/apply/apply.go @@ -3,10 +3,10 @@ // Three properties, each following a recorded decision, and each of them the difference // between this and a script that writes files: // -// - A failed step fails the apply (novox/hq ADR 0008). Not "logs and continues": a partial +// - A failed step fails the apply (novox/hq ADR 0010). Not "logs and continues": a partial // apply that reports success is the mesh's most expensive shape. // - Every applier READS BACK. Setting a value is not evidence the value took. -// - What was applied is recorded after it works, never before (ADR 0035). A failed apply +// - What was applied is recorded after it works, never before (ADR 0018). A failed apply // leaves the machine in whatever state it reached, and nothing must claim otherwise. package apply @@ -29,7 +29,7 @@ import ( ) // Runner executes a command. The real one is used everywhere outside unit tests; behaviour -// against a real system is tested alongside rather than mocked (novox/hq ADR 0034). +// against a real system is tested alongside rather than mocked (novox/hq ADR 0017). type Runner = system.Runner // Outcome is what happened to one resource. @@ -379,7 +379,7 @@ func applyService(ctx context.Context, sys system.System, r *declaration.Service // what it actually did. // // Only ever called for something in the store, which is what bounds it: the host is -// authoritative over its own footprint and inert everywhere else (novox/hq ADR 0043). +// authoritative over its own footprint and inert everywhere else (novox/hq ADR 0005). // // It returns the action rather than assuming "removed", because for half the vocabulary the // honest word is "forgotten". A host that reported a package removed when it left the package @@ -469,7 +469,7 @@ func ExecRunner(ctx context.Context, name string, args ...string) (string, error // // It never upgrades and never removes. "Present" is the whole of what a package resource // asserts, because version is the package manager's business and the mesh does not have a -// second opinion about it (novox/hq ADR 0041 — the host depends on nothing, and that includes +// second opinion about it (novox/hq ADR 0005 — the host depends on nothing, and that includes // not becoming a second package manager). func applyPackage(ctx context.Context, sys system.System, r *declaration.Package, run Runner) (Outcome, error) { out := begin(r) @@ -641,7 +641,7 @@ func sortedKeys(m map[string]string) []string { // idempotency check and the read-back. Running it first is how the host knows whether there is // anything to do — it does not know what a database is, so "is the database there" is a // question only the declaration can ask. Running it again afterwards is how the host knows the -// command had the effect it claimed (novox/hq ADR 0047). +// command had the effect it claimed (novox/hq ADR 0005). func applyAction(ctx context.Context, r *declaration.Action, run Runner) (Outcome, error) { out := begin(r) @@ -682,7 +682,7 @@ func runAction(ctx context.Context, r *declaration.Action, argv []string, run Ru // // Two, because two exist on machines the mesh runs on. The list is short on purpose: each entry // is a claim that its probe and its CLI have been checked, not that a binary of that name might -// work (novox/hq ADR 0060). +// work (novox/hq ADR 0005). // // The probe differs and the rest does not, which is what makes this a lookup rather than an // interface. `docker info --format {{.ServerVersion}}` fails on podman — the field does not diff --git a/internal/apply/apply_test.go b/internal/apply/apply_test.go index 7218f0c..bc819f8 100644 --- a/internal/apply/apply_test.go +++ b/internal/apply/apply_test.go @@ -13,7 +13,7 @@ import ( "github.com/novox/mesh-host/internal/system" ) -// Each test names the decision it defends (novox/hq ADR 0034). +// Each test names the decision it defends (novox/hq ADR 0017). func parse(t *testing.T, raw string) *declaration.Declaration { t.Helper() @@ -87,7 +87,7 @@ func TestADriftedMachineIsReturned(t *testing.T) { } func TestADroppedResourceIsRemoved(t *testing.T) { - // novox/hq ADR 0043: the host removes what it previously applied and is no longer + // novox/hq ADR 0005: the host removes what it previously applied and is no longer // declared. Removing a line from a declaration is an act with an effect. dir := t.TempDir() keep := filepath.Join(dir, "keep.conf") @@ -178,7 +178,7 @@ func TestARenameToTheSamePathDoesNotDeleteTheNewFile(t *testing.T) { } func TestAFailedStepFailsTheApply(t *testing.T) { - // novox/hq ADR 0008. And the error carries what HAD been done, because the machine is in + // novox/hq ADR 0010. And the error carries what HAD been done, because the machine is in // whatever state the apply reached and the only honest thing to hand back is that list. dir := t.TempDir() blocker := filepath.Join(dir, "blocker") @@ -214,7 +214,7 @@ func TestAFailedStepFailsTheApply(t *testing.T) { } func TestNothingIsRecordedUntilItWorked(t *testing.T) { - // novox/hq ADR 0035. A record written before the fact restates the request in a new place + // novox/hq ADR 0018. A record written before the fact restates the request in a new place // and inherits none of the authority of having happened. dir := t.TempDir() blocker := filepath.Join(dir, "blocker") @@ -416,7 +416,7 @@ func TestForgettingAUnitThatIsGoneDoesNotStrandTheNode(t *testing.T) { } } -// --- package, container and action (novox/hq 07-the-substrate.md, ADR 0046, ADR 0047) --- +// --- package, container and action (novox/hq 07-the-substrate.md, ADR 0006, ADR 0005) --- func parseTrusted(t *testing.T, raw string) *declaration.Declaration { t.Helper() @@ -831,7 +831,7 @@ func TestAnUnknownBootStateIsRefusedNotGuessed(t *testing.T) { } } -// --- more than one container runtime (novox/hq ADR 0060) --- +// --- more than one container runtime (novox/hq ADR 0005) --- func TestTheRuntimeProbeIsPerRuntime(t *testing.T) { // Verified against a real podman 6.1.0 before this was written: diff --git a/internal/bundle/bundle.go b/internal/bundle/bundle.go index 5b21b6a..856da0f 100644 --- a/internal/bundle/bundle.go +++ b/internal/bundle/bundle.go @@ -1,11 +1,11 @@ // Package bundle is the declaration the host carries. // -// novox/hq ADR 0038: the host has one behaviour and two sources of declaration — the control +// novox/hq ADR 0004: the host has one behaviour and two sources of declaration — the control // plane when a mesh is reachable, and this when none is. The first node is not a different // kind of node; it is a node whose mesh is not up yet, and this is what it applies until it is. // // Carried inside the binary rather than beside it, because "copy it onto a machine and run it -// is the whole installation" (ADR 0041) stops being true the moment a second file has to +// is the whole installation" (ADR 0005) stops being true the moment a second file has to // arrive with it. package bundle @@ -20,7 +20,7 @@ import ( // One bundle per operating system, because its CONTENTS are per system even though its // mechanism is not: package names, unit names and service names all differ -// (novox/hq ADR 0060). All three are embedded and the host applies the one it was built for — +// (novox/hq ADR 0005). All three are embedded and the host applies the one it was built for — // an arch host never reads the alpine bundle. // // A host whose bundle is only comments carries nothing, and says so rather than applying @@ -76,7 +76,7 @@ func Load(system string) (*declaration.Declaration, error) { return nil, ErrEmpty } // ParseTrusted: the bundle arrives with the binary, so it may carry actions the link may - // not (novox/hq ADR 0047). The bootstrap needs them — creating the control plane's database + // not (novox/hq ADR 0005). The bootstrap needs them — creating the control plane's database // happens before there is any mesh to ask for one. return declaration.ParseTrusted(stripComments(locks[system])) } diff --git a/internal/declaration/declaration.go b/internal/declaration/declaration.go index 0fa9af2..486d9e4 100644 --- a/internal/declaration/declaration.go +++ b/internal/declaration/declaration.go @@ -3,7 +3,7 @@ // Data, never instructions. The vocabulary is finite, versioned, and anything outside it // refuses the whole declaration rather than being skipped — a host that applied most of what // it was sent and reported success is a node that looks configured and is not -// (novox/hq ADR 0043). +// (novox/hq ADR 0005). package declaration import ( @@ -162,7 +162,7 @@ type Container struct { ID string `json:"id"` Type Type `json:"type"` Name string `json:"name"` - // Image is pinned by digest (novox/hq ADR 0046) — a tag moves and a digest does not. + // Image is pinned by digest (novox/hq ADR 0006) — a tag moves and a digest does not. Image string `json:"image"` Env map[string]string `json:"env,omitempty"` Ports []string `json:"ports,omitempty"` @@ -189,7 +189,7 @@ type Action struct { Command []string `json:"command"` // Verify is not optional and is not a courtesy. It is the read-back AND the idempotency // check: the host does not know what a database is, so "is it already there" is a question - // only the declaration can ask (novox/hq ADR 0047). + // only the declaration can ask (novox/hq ADR 0005). Verify []string `json:"verify"` // In names a container to run inside. Empty means the machine itself. In string `json:"in,omitempty"` @@ -207,7 +207,7 @@ func (a *Action) Target() string { } func (a *Action) validate(where string, allowActions bool) []string { - // The bound the whole security argument rests on (novox/hq ADR 0047). + // The bound the whole security argument rests on (novox/hq ADR 0005). if !allowActions { return []string{where + ": an action arrived over the link, and the link may not carry one. The host " + @@ -264,7 +264,7 @@ type Declaration struct { // nothing to check against. For string // Resources, in the order they are applied. The host does not sort them: ordering is a - // decision, and deciding is not what the host does (novox/hq ADR 0037). + // decision, and deciding is not what the host does (novox/hq ADR 0005). Resources []Resource } @@ -286,14 +286,14 @@ func (e *RefusalError) Error() string { } // Parse reads a declaration that arrived over the link, and refuses anything it does not fully -// understand — including any action, which the link may not carry (novox/hq ADR 0047). +// understand — including any action, which the link may not carry (novox/hq ADR 0005). func Parse(raw []byte) (*Declaration, error) { return parse(raw, false) } // ParseTrusted reads a declaration from a source already as privileged as the host itself: the // bundle it carries, or a file handed to it by someone who is running it as root. // // Actions are permitted here and nowhere else. The asymmetry is deliberate and is the entire -// content of ADR 0047: refusing actions from the bundle buys nothing, because whoever built the +// content of ADR 0005: refusing actions from the bundle buys nothing, because whoever built the // bundle built the binary; refusing them from the link buys the bound on what a compromised // control plane can express. func ParseTrusted(raw []byte) (*Declaration, error) { return parse(raw, true) } @@ -450,7 +450,7 @@ func checkMode(where, mode string) []string { // checkImage insists on a digest. // // A tag moves and a digest does not. The bundle's whole claim is that what it names is exact -// (novox/hq ADR 0046), and a bundle pinning `postgres:17` pins nothing — it names whatever +// (novox/hq ADR 0006), and a bundle pinning `postgres:17` pins nothing — it names whatever // that tag points at on the day the host happens to run. func checkImage(where, image string) []string { if image == "" { diff --git a/internal/declaration/declaration_test.go b/internal/declaration/declaration_test.go index dc755ef..0a647b7 100644 --- a/internal/declaration/declaration_test.go +++ b/internal/declaration/declaration_test.go @@ -6,7 +6,7 @@ import ( "testing" ) -// Each test names the decision it defends (novox/hq ADR 0034). The decision here is ADR 0043, +// Each test names the decision it defends (novox/hq ADR 0017). The decision here is ADR 0005, // and the property it turns on is that unknown is REFUSED, never skipped. func valid() string { @@ -160,7 +160,7 @@ func TestAnEmptyDeclarationIsAMistake(t *testing.T) { // --- the vocabulary the substrate bootstrap needs (novox/hq 07-the-substrate.md) --- func TestAnActionOverTheLinkIsRefused(t *testing.T) { - // novox/hq ADR 0047. The link may push declarations of known shape and never a command to + // novox/hq ADR 0005. The link may push declarations of known shape and never a command to // run. This is the boundary the whole security argument rests on, so it is asserted // directly rather than inferred from the type list. raw := []byte(`{"declaration":1,"resources":[ @@ -195,7 +195,7 @@ func TestAnActionWithoutVerifyIsRefused(t *testing.T) { } func TestAnImageMustBePinnedByDigest(t *testing.T) { - // novox/hq ADR 0046: reproducibility comes from pinning the identity of a thing. A bundle + // novox/hq ADR 0006: reproducibility comes from pinning the identity of a thing. A bundle // naming a tag pins nothing — it names whatever that tag points at on the day it runs. for _, image := range []string{ "postgres:17", diff --git a/internal/inventory/inventory.go b/internal/inventory/inventory.go index 6437eb1..c6a10d6 100644 --- a/internal/inventory/inventory.go +++ b/internal/inventory/inventory.go @@ -3,7 +3,7 @@ // Reported upward and never asked downward (novox/hq 03-DESIGN/01-to-be/05-the-node-host.md). // Everything here is read from the machine at the moment of asking — nothing is remembered, // nothing is derived from a file that says what the machine ought to be -// (novox/hq ADR 0035). +// (novox/hq ADR 0018). package inventory import ( @@ -39,7 +39,7 @@ type Inventory struct { // ObservedAt is when this was read. An inventory with no timestamp cannot be told from a // stale one, and a node that has been unreachable for a week is an ordinary situation - // (novox/hq ADR 0036) rather than an error — so the age of the observation is part of it. + // (novox/hq ADR 0004) rather than an error — so the age of the observation is part of it. ObservedAt time.Time `json:"observed_at"` // Unreadable lists what could not be determined, and why. An absent field and a field that diff --git a/internal/inventory/inventory_test.go b/internal/inventory/inventory_test.go index b0dfdb0..a3b0dce 100644 --- a/internal/inventory/inventory_test.go +++ b/internal/inventory/inventory_test.go @@ -64,7 +64,7 @@ func TestMemoryIsReadOrReportedMissing(t *testing.T) { } func TestTheInventorySaysWhenItWasTaken(t *testing.T) { - // A node unreachable for a week is an ordinary situation (novox/hq ADR 0036), so an + // A node unreachable for a week is an ordinary situation (novox/hq ADR 0004), so an // inventory that cannot be told from a stale one is missing the fact that matters. before := time.Now().UTC() inv := Collect(context.Background(), nil, nil, time.Second) @@ -79,7 +79,7 @@ func TestTheInventorySaysWhenItWasTaken(t *testing.T) { func TestTheHostDoesNotNameTheNode(t *testing.T) { // A node's name is assigned by the mesh. A host that named itself would be deciding - // something, which is precisely what novox/hq ADR 0037 forbids it to do. + // something, which is precisely what novox/hq ADR 0005 forbids it to do. inv := Collect(context.Background(), nil, nil, time.Second) hostname, _ := os.Hostname() @@ -91,7 +91,7 @@ func TestTheHostDoesNotNameTheNode(t *testing.T) { // --- against this machine --------------------------------------------------------------- func TestAgainstThisMachine_inventoryIsTrue(t *testing.T) { - // novox/hq ADR 0034: behaviour against a real system is tested alongside, not mocked. + // novox/hq ADR 0017: behaviour against a real system is tested alongside, not mocked. inv := Collect(context.Background(), nil, profile.Default(nil), 10*time.Second) if inv.Machine == "" { diff --git a/internal/profile/detectors.go b/internal/profile/detectors.go index e9ca9cf..f20d4f6 100644 --- a/internal/profile/detectors.go +++ b/internal/profile/detectors.go @@ -111,7 +111,7 @@ func firstLine(s string) string { // privileged reports whether the host can change this machine at all. // // Reported as a capability rather than checked at startup on purpose: a host that cannot act -// is still a host that can report, and novox/hq ADR 0036 says what varies between nodes lives +// is still a host that can report, and novox/hq ADR 0004 says what varies between nodes lives // here rather than in the definition of a node. type privileged struct{} diff --git a/internal/profile/profile.go b/internal/profile/profile.go index 5ce7d70..ace9572 100644 --- a/internal/profile/profile.go +++ b/internal/profile/profile.go @@ -44,7 +44,7 @@ type Detector interface { // Runner executes a command. Replaceable in tests for the pure-logic layer ONLY — every // detector in this package is exercised against the real machine as well, because a test that // fakes the system under detection asserts that the fake behaves as expected -// (novox/hq ADR 0034). +// (novox/hq ADR 0017). type Runner func(ctx context.Context, name string, args ...string) (stdout string, err error) // ExecRunner runs a real command, with output captured and stdin closed. @@ -97,7 +97,7 @@ func (p Profile) Missing() []string { // Detect runs every detector and collects the verdicts. // // A detector that fails does not fail the profile. This is deliberately NOT the rule in -// novox/hq ADR 0008: that rule governs applying state, where a failed step means the machine +// novox/hq ADR 0010: that rule governs applying state, where a failed step means the machine // is not what was asked for. Detection is the opposite — a failed probe is a finding, and the // finding is "absent, because the probe failed", which is exactly what a caller needs to know. // Aborting would replace one legible absence with total ignorance. diff --git a/internal/profile/profile_system_test.go b/internal/profile/profile_system_test.go index a6b58f2..882f1dd 100644 --- a/internal/profile/profile_system_test.go +++ b/internal/profile/profile_system_test.go @@ -8,7 +8,7 @@ import ( "time" ) -// Against the real machine. novox/hq ADR 0034: structure and logic are tested first, behaviour +// Against the real machine. novox/hq ADR 0017: structure and logic are tested first, behaviour // against a real system alongside, and mocking the boundary is forbidden — a test that fakes // the system under detection asserts that the fake behaves as expected. // diff --git a/internal/profile/profile_test.go b/internal/profile/profile_test.go index 926238d..9c844ed 100644 --- a/internal/profile/profile_test.go +++ b/internal/profile/profile_test.go @@ -8,7 +8,7 @@ import ( "time" ) -// The decision each test defends is named in the test, per novox/hq ADR 0034. These cover +// The decision each test defends is named in the test, per novox/hq ADR 0017. These cover // structure and logic; profile_system_test.go covers the same detectors against the real // machine, because a test that fakes the system under detection asserts only that the fake // behaves as expected. @@ -57,7 +57,7 @@ func TestEveryVerdictSaysHowItKnows(t *testing.T) { } func TestDetectionSurvivesAFailingProbe(t *testing.T) { - // Deliberately NOT ADR 0008. That rule governs APPLYING state, where a failed step means + // Deliberately NOT ADR 0010. That rule governs APPLYING state, where a failed step means // the machine is not what was asked for. A failed probe is a finding, and aborting would // replace one legible absence with total ignorance of the rest. only := func(ctx context.Context, name string, args ...string) (string, error) { diff --git a/internal/store/store.go b/internal/store/store.go index 07d3020..e1f5165 100644 --- a/internal/store/store.go +++ b/internal/store/store.go @@ -1,11 +1,11 @@ // Package store is what this node knows about itself, and it is authoritative while // disconnected. // -// Not a cache of the control plane. novox/hq ADR 0036 makes disconnection an ordinary +// Not a cache of the control plane. novox/hq ADR 0004 makes disconnection an ordinary // situation rather than an exception, and this is what makes it ordinary: a machine shut for a // week comes back and reconciles, it does not come back and ask what it is. // -// Its first job arrives with the first apply rather than with the link (ADR 0043): the host +// Its first job arrives with the first apply rather than with the link (ADR 0005): the host // removes what it previously applied and is no longer declared, and it can only know that // because it wrote it down. package store @@ -27,7 +27,7 @@ const DefaultPath = "/var/lib/mesh-host/state.json" // Applied is one resource the host put on this machine, and what it did. // -// Recorded AFTER the resource was applied and read back, never before (novox/hq ADR 0035). +// Recorded AFTER the resource was applied and read back, never before (novox/hq ADR 0018). // A record written up front restates the request in a new place and inherits none of the // authority of having happened. type Applied struct { @@ -164,7 +164,7 @@ func (s *State) Forget(id string) { // // Reverse order because undoing in the order things were made undoes a directory before the // file inside it. Reversing is the only ordering the host can derive without deciding -// anything, which is the line novox/hq ADR 0037 draws. +// anything, which is the line novox/hq ADR 0005 draws. func (s State) Orphans(declared map[string]bool) []Applied { var out []Applied for i := len(s.Resources) - 1; i >= 0; i-- { diff --git a/internal/system/android.go b/internal/system/android.go index ec39b4f..ec53363 100644 --- a/internal/system/android.go +++ b/internal/system/android.go @@ -13,7 +13,7 @@ import ( // way to run something — and refuses the other three. That is not a broken host: a declaration // naming a shape this host does not implement is refused whole, the same treatment an unknown // type gets, and the profile tells the control plane which shapes exist so it never sends one -// it cannot do (novox/hq ADR 0060). +// it cannot do (novox/hq ADR 0005). // // What it cannot do, and why: // @@ -24,13 +24,13 @@ import ( // and an unlocked bootloader. On a normal device nothing can register with it. // - **container** — no container runtime, and no kernel access to give one. // -// **This host is EPISODIC** (novox/hq ADR 0062). Everywhere else an init runs the launcher at +// **This host is EPISODIC** (novox/hq ADR 0005). Everywhere else an init runs the launcher at // boot and the launcher supervises the host. Android grants neither: nothing to register with // without root, and nothing worth supervising, because a supervisor would be killed alongside // what it supervises. // // So it runs when the platform allows and is killed when the platform wants the memory — and -// that is **disconnection**, which ADR 0036 already made an ordinary situation rather than an +// that is **disconnection**, which ADR 0004 already made an ordinary situation rather than an // exception. It needs no keep-alive and no new mechanism: the store is already authoritative // while disconnected, reconcile already happens on start, and the mesh already reports *last // heard from* rather than alarming on silence. diff --git a/internal/system/system.go b/internal/system/system.go index 4474f1b..c1edebb 100644 --- a/internal/system/system.go +++ b/internal/system/system.go @@ -1,6 +1,6 @@ // Package system is the part of the host that differs between operating systems. // -// novox/hq ADR 0060. A machine has apk because it is Alpine; the package manager, the service +// novox/hq ADR 0005. A machine has apk because it is Alpine; the package manager, the service // manager and the packaging format arrive together as one decision somebody made at install // time. So they are not independent knobs — they are one implementation, named after the system // it belongs to. @@ -75,7 +75,7 @@ func Supports(s System, t declaration.Type) bool { // Check refuses a declaration naming a shape this host cannot apply. // // Refused whole and before anything is applied, which is the same treatment an unknown type -// gets (novox/hq ADR 0043) — a host that applied the parts it understood would leave a machine +// gets (novox/hq ADR 0005) — a host that applied the parts it understood would leave a machine // that looks configured and is not. The reason differs and the outcome does not. func Check(s System, d *declaration.Declaration) error { var problems []string @@ -116,7 +116,7 @@ func everyShape() []declaration.Type { // portableShapes need only a filesystem and a way to run something. // // The floor. A host that can do nothing else can still do these, which is what makes a partial -// host a real thing rather than a broken one (novox/hq ADR 0060). +// host a real thing rather than a broken one (novox/hq ADR 0005). func portableShapes() []declaration.Type { return []declaration.Type{ declaration.TypeDirectory, declaration.TypeFile, declaration.TypeAction, diff --git a/internal/system/system_test.go b/internal/system/system_test.go index aa6ca5b..5c8a312 100644 --- a/internal/system/system_test.go +++ b/internal/system/system_test.go @@ -238,7 +238,7 @@ func TestOpenRCBootStateComesFromTheRunlevel(t *testing.T) { } func TestEachSystemUsesItsOwnCommands(t *testing.T) { - // The whole point of ADR 0060: the alpine host must never reach for systemctl, and the arch + // The whole point of ADR 0005: the alpine host must never reach for systemctl, and the arch // host must never reach for rc-service. for _, tc := range []struct{ name, forbidden string }{ {"arch", "rc-service"}, diff --git a/internal/upgrade/upgrade.go b/internal/upgrade/upgrade.go index 06ab953..082ea4c 100644 --- a/internal/upgrade/upgrade.go +++ b/internal/upgrade/upgrade.go @@ -1,6 +1,6 @@ // Package upgrade is how the host survives replacing itself. // -// novox/hq ADR 0057 and ADR 0059. Two facts, and neither is the host judging its own health: +// novox/hq ADR 0005 and ADR 0005. Two facts, and neither is the host judging its own health: // // - whether the executable this process started from has been replaced on disk, which is how // it knows to stand aside for a new one; @@ -42,7 +42,7 @@ type Self struct { // // path is what os.Executable() returned; a test passes one it can manipulate, because the // boundary being tested is the filesystem and a fake would assert that the fake behaves as -// expected (novox/hq ADR 0034). +// expected (novox/hq ADR 0017). func Current(path string) (Self, error) { info, err := os.Stat(path) if err != nil { diff --git a/internal/upgrade/upgrade_test.go b/internal/upgrade/upgrade_test.go index e2ec715..ecf3e63 100644 --- a/internal/upgrade/upgrade_test.go +++ b/internal/upgrade/upgrade_test.go @@ -11,7 +11,7 @@ import ( // // Against the real filesystem rather than a fake one. What is being tested is how the operating // system behaves when a file is replaced under a running process, and a fake would assert that -// the fake behaves as expected (novox/hq ADR 0034). +// the fake behaves as expected (novox/hq ADR 0017). func started(t *testing.T) (Self, string) { t.Helper() binary := filepath.Join(t.TempDir(), "mesh-host") diff --git a/packaging/launch_test.sh b/packaging/launch_test.sh index 7233f69..014e246 100755 --- a/packaging/launch_test.sh +++ b/packaging/launch_test.sh @@ -141,7 +141,7 @@ done # These need the launcher to actually run as a supervisor rather than one iteration, so they do # not set MESH_HOST_RUN_ONCE. -# A host that exits 0 has upgraded itself and stood aside (novox/hq ADR 0057). The launcher must +# A host that exits 0 has upgraded itself and stood aside (novox/hq ADR 0005). The launcher must # start it again — and must NOT count it, because it did not fail. setup unset MESH_HOST_RUN_ONCE diff --git a/packaging/nox-mesh-host-launch b/packaging/nox-mesh-host-launch index 7949591..b2a5495 100755 --- a/packaging/nox-mesh-host-launch +++ b/packaging/nox-mesh-host-launch @@ -1,7 +1,7 @@ #!/bin/sh # Supervise the host: start it, watch it, and decide what to do when it stops. # -# novox/hq ADR 0061. The init is asked for ONE thing — run this at boot — and everything else +# novox/hq ADR 0005. The init is asked for ONE thing — run this at boot — and everything else # lives here, in a script that can be tested. Whether to restart, how long to wait, when to give # up, when to roll back: all of it is policy, and policy in a unit file can only be read and # hoped for. @@ -109,7 +109,7 @@ while :; do case "$status" in 0) # Exited cleanly. That is how the host stands aside for a new binary after an - # upgrade (novox/hq ADR 0057) — so loop and run whatever is now on disk. + # upgrade (novox/hq ADR 0005) — so loop and run whatever is now on disk. # # Deliberately NOT counted, and this is the whole reason the counter is # incremented here rather than before the start: counting attempts meant a host diff --git a/packaging/nox-mesh-host-rollback b/packaging/nox-mesh-host-rollback index 7c44591..f0608a3 100755 --- a/packaging/nox-mesh-host-rollback +++ b/packaging/nox-mesh-host-rollback @@ -1,7 +1,7 @@ #!/bin/sh # Put the host back on the last version that worked. # -# novox/hq ADR 0059. This runs when nox-mesh-host will not start, so it shares no code with it +# novox/hq ADR 0005. This runs when nox-mesh-host will not start, so it shares no code with it # and calls none of it: a binary that cannot start cannot be its own recovery. POSIX sh, no # bashisms, nothing that has to be installed. # @@ -60,6 +60,6 @@ if ! pacman -U --noconfirm "$PKG"; then fi # Deliberately does NOT start anything. The launcher called this and will exec the host next, -# so starting it here would run two. novox/hq ADR 0061 moved that responsibility; this script +# so starting it here would run two. novox/hq ADR 0005 moved that responsibility; this script # installs a version and says so, and nothing else. say "rolled back to $VERSION. the launcher will start it." diff --git a/packaging/nox-mesh-host.openrc b/packaging/nox-mesh-host.openrc index 2e7ee1a..cc740f0 100644 --- a/packaging/nox-mesh-host.openrc +++ b/packaging/nox-mesh-host.openrc @@ -1,7 +1,7 @@ #!/sbin/openrc-run # The Alpine equivalent of the systemd unit beside this. Four lines of the same two facts: # run the launcher, and bring it back if it dies. Everything else is in the launcher, which is -# what makes a second init transcription rather than a port (novox/hq ADR 0061). +# what makes a second init transcription rather than a port (novox/hq ADR 0005). name="nox-mesh-host" command="/usr/lib/nox-mesh-host/launch" supervisor="supervise-daemon" diff --git a/packaging/nox-mesh-host.service b/packaging/nox-mesh-host.service index d7cf366..c9c6df1 100644 --- a/packaging/nox-mesh-host.service +++ b/packaging/nox-mesh-host.service @@ -3,7 +3,7 @@ Description=Novox Mesh node host After=network-online.target Wants=network-online.target -# One line of policy: run the launcher at boot (novox/hq ADR 0061). Restarting the host, +# One line of policy: run the launcher at boot (novox/hq ADR 0005). Restarting the host, # backing off, giving up and rolling back are all the launcher's, where they can be tested. # Restart= here is a backstop for the launcher itself being killed, not the mechanism. [Service] diff --git a/packaging/rollback_test.sh b/packaging/rollback_test.sh index 6fcb7aa..27e71ba 100755 --- a/packaging/rollback_test.sh +++ b/packaging/rollback_test.sh @@ -47,7 +47,7 @@ touch "$MESH_HOST_PKG_CACHE/nox-mesh-host-1.4.2-1-x86_64.pkg.tar.zst" check "installs the known-good version" "pacman is asked to install the cached package" \ "$(grep -c 'nox-mesh-host-1.4.2' "$MESH_HOST_STATE_DIR/pacman.calls" 2>/dev/null || echo 0)" "1" # It installs and stops. The launcher execs the host next, and starting it here would run two -# (novox/hq ADR 0061). +# (novox/hq ADR 0005). check "does not start anything itself" "the launcher owns starting" \ "$([ -f "$MESH_HOST_STATE_DIR/systemctl.calls" ] && echo started || echo not-started)" "not-started" check "records that it rolled back" "the attempted marker holds the version" \