diff --git a/checks/owned/go.mod b/checks/owned/go.mod new file mode 100644 index 00000000..d1c4739a --- /dev/null +++ b/checks/owned/go.mod @@ -0,0 +1,3 @@ +module git.novox.be/novox/mesh-catalog/checks/owned + +go 1.22 diff --git a/checks/owned/main.go b/checks/owned/main.go new file mode 100644 index 00000000..09512d5d --- /dev/null +++ b/checks/owned/main.go @@ -0,0 +1,236 @@ +// Command owned judges how the catalogue's directories and archives treat files they did not write (novox/hq +// ADR 0422 §8, issue 1024). It refuses, naming the module, the resource and the reason: +// +// 1. a directory or archive without `unknown`, or with a value but move-out, module or program; +// +// 2. `move-out` on a path not under ${machine:account-home} or ${machine:agent-home}; +// +// 3. `knows` with an empty, absolute, `.`/`..`/empty-component or repeated path; +// +// 4. a path one module declares (a resource's path, or a fact with "home": true) lying inside a directory of +// another module, after ${dir:} is resolved within each module and both homes are read as one root. +// Archives are not containers for this rule. This holds for ~/.ssh what checks/sshdir held (ADR 0415 §6). +// +// go run . +// +// Exits 1 on a finding. +package main + +import ( + "encoding/json" + "fmt" + "os" + "path" + "path/filepath" + "regexp" + "sort" + "strings" +) + +// Home is the one root both machine homes are read as. +const Home = "${home}" + +var ( + ofDir = regexp.MustCompile(`\$\{dir:([a-z0-9][a-z0-9_-]*)\}`) + homeVar = strings.NewReplacer("${machine:account-home}", Home, "${machine:agent-home}", Home) + values = map[string]bool{"move-out": true, "module": true, "program": true} +) + +// Finding is one refusal. +type Finding struct { + Rule int + Module, ID, Why string +} + +type resource struct { + ID, Type, Path, Unknown string + Knows []string + HasKnows bool +} + +type parsed struct { + Module string + Resources []resource + Facts []string // paths of facts with "home": true, under the home +} + +func load(file string) (*parsed, error) { + raw, err := os.ReadFile(file) + if err != nil { + return nil, err + } + var m struct { + Module string `json:"module"` + Resources []struct { + ID string `json:"id"` + Type string `json:"type"` + Path string `json:"path"` + Unknown *string `json:"unknown"` + Knows []string `json:"knows"` + } `json:"resources"` + Facts map[string]struct { + Path string `json:"path"` + Home bool `json:"home"` + } `json:"facts"` + } + if err := json.Unmarshal(raw, &m); err != nil { + return nil, fmt.Errorf("%s: %w", file, err) + } + out := &parsed{Module: m.Module} + if out.Module == "" { + out.Module = filepath.Base(filepath.Dir(file)) + } + for _, r := range m.Resources { + x := resource{ID: r.ID, Type: r.Type, Path: r.Path, Knows: r.Knows, HasKnows: r.Knows != nil} + if r.Unknown != nil { + x.Unknown = *r.Unknown + if x.Unknown == "" { + x.Unknown = "(empty)" + } + } + out.Resources = append(out.Resources, x) + } + keys := make([]string, 0, len(m.Facts)) + for k := range m.Facts { + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + if f := m.Facts[k]; f.Home && f.Path != "" { + out.Facts = append(out.Facts, f.Path) + } + } + return out, nil +} + +// norm resolves ${dir:} from the module's own resources, reads both homes as one root and cleans the path. +func norm(p string, dirs map[string]string) string { + for i := 0; i < 8 && ofDir.MatchString(p); i++ { + p = ofDir.ReplaceAllStringFunc(p, func(w string) string { + if to, ok := dirs[ofDir.FindStringSubmatch(w)[1]]; ok { + return to + } + return w + }) + } + p = homeVar.Replace(p) + if p == "" { + return "" + } + return path.Clean(p) +} + +func underHome(p string) bool { return strings.HasPrefix(p, Home+"/") } + +// badKnows says why a knows entry is refused, or "". +func badKnows(k string) string { + if k == "" { + return "is empty" + } + if strings.HasPrefix(k, "/") { + return "is absolute" + } + for _, c := range strings.Split(strings.TrimSuffix(k, "/"), "/") { + if c == "" || c == "." || c == ".." { + return "has an empty, . or .. component" + } + } + return "" +} + +type declared struct { + module, id, path string +} + +// Check reads every manifest under root/modules and answers what it refuses. +func Check(root string) ([]Finding, error) { + files, err := filepath.Glob(filepath.Join(root, "modules", "*", "module.json")) + if err != nil { + return nil, err + } + sort.Strings(files) + var out []Finding + var paths []declared + type container struct{ module, path string } + var containers []container + for _, file := range files { + m, err := load(file) + if err != nil { + return nil, err + } + dirs := map[string]string{} + for _, r := range m.Resources { + if r.ID != "" && r.Path != "" { + dirs[r.ID] = r.Path + } + } + for _, r := range m.Resources { + p := norm(r.Path, dirs) + if p != "" { + paths = append(paths, declared{m.Module, r.ID, p}) + } + if r.Type != "directory" && r.Type != "archive" { + continue + } + if r.Type == "directory" && p != "" { + containers = append(containers, container{m.Module, p}) + } + add := func(rule int, why string) { out = append(out, Finding{rule, m.Module, r.ID, why}) } + switch { + case r.Unknown == "": + add(1, "a "+r.Type+" without `unknown` (move-out, module or program)") + case !values[r.Unknown]: + add(1, fmt.Sprintf("`unknown` is %q, not move-out, module or program", r.Unknown)) + case r.Unknown == "move-out" && !underHome(p): + add(2, fmt.Sprintf("`move-out` on %q, which is not under ${machine:account-home} or ${machine:agent-home}", r.Path)) + } + seen := map[string]bool{} + for _, k := range r.Knows { + if why := badKnows(k); why != "" { + add(3, fmt.Sprintf("`knows` entry %q %s", k, why)) + continue + } + c := strings.TrimSuffix(k, "/") + if seen[c] { + add(3, fmt.Sprintf("`knows` entry %q is repeated", k)) + } + seen[c] = true + } + if r.HasKnows && len(r.Knows) == 0 { + add(3, "`knows` is empty") + } + } + for _, f := range m.Facts { + if p := norm(Home+"/"+f, nil); p != "" { + paths = append(paths, declared{m.Module, "fact " + f, p}) + } + } + } + for _, d := range paths { + for _, c := range containers { + if c.module != d.module && (d.path == c.path || strings.HasPrefix(d.path, c.path+"/")) { + out = append(out, Finding{4, d.module, d.id, fmt.Sprintf("declares %q, inside a directory of %s (%q)", d.path, c.module, c.path)}) + } + } + } + return out, nil +} + +func main() { + root := "." + if len(os.Args) > 1 { + root = os.Args[1] + } + found, err := Check(root) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + for _, f := range found { + fmt.Printf("%s: %s: %s (rule %d, novox/hq ADR 0422 §8, issue 1024)\n", f.Module, f.ID, f.Why, f.Rule) + } + if len(found) > 0 { + os.Exit(1) + } + fmt.Println("owned paths: every directory and archive says how it treats unknown files; no module declares inside another's directory") +} diff --git a/checks/owned/main_test.go b/checks/owned/main_test.go new file mode 100644 index 00000000..0882ba47 --- /dev/null +++ b/checks/owned/main_test.go @@ -0,0 +1,132 @@ +package main + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +func manifest(t *testing.T, root, module, body string) { + t.Helper() + dir := filepath.Join(root, "modules", module) + if err := os.MkdirAll(dir, 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(dir, "module.json"), []byte(body), 0o644); err != nil { + t.Fatal(err) + } +} + +func check(t *testing.T, root string) []Finding { + t.Helper() + found, err := Check(root) + if err != nil { + t.Fatal(err) + } + return found +} + +// only asserts exactly one finding, of the rule, naming the module and the resource (issue 1024). +func only(t *testing.T, found []Finding, rule int, module, id string) { + t.Helper() + if len(found) != 1 || found[0].Rule != rule || found[0].Module != module || found[0].ID != id || found[0].Why == "" { + t.Fatalf("found %+v; want one finding of rule %d for %s/%s with a reason", found, rule, module, id) + } +} + +func dir(id, path, rest string) string { + return `{"id":"` + id + `","type":"directory","path":"` + path + `"` + rest + `}` +} + +func mod(name string, resources ...string) string { + return `{"module":"` + name + `","resources":[` + strings.Join(resources, ",") + `]}` +} + +func TestMissingOrUnknownValueIsRefused(t *testing.T) { + root := t.TempDir() + manifest(t, root, "a", mod("a", dir("d", "/var/lib/a", ""))) + only(t, check(t, root), 1, "a", "d") + + root = t.TempDir() + manifest(t, root, "a", mod("a", `{"id":"z","type":"archive","path":"/opt/a","unknown":"delete"}`)) + only(t, check(t, root), 1, "a", "z") +} + +func TestMoveOutOutsideAHomeIsRefused(t *testing.T) { + root := t.TempDir() + manifest(t, root, "a", mod("a", dir("d", "/etc/a.d", `,"unknown":"move-out"`))) + only(t, check(t, root), 2, "a", "d") +} + +func TestMoveOutUnderAHomeIsAllowed(t *testing.T) { + root := t.TempDir() + manifest(t, root, "a", mod("a", + dir("d", "${machine:account-home}/.config/a", `,"unknown":"move-out"`), + dir("e", "${dir:d}/sub", `,"unknown":"move-out"`), + dir("f", "${machine:agent-home}/x", `,"unknown":"move-out"`), + dir("g", "/var/lib/a", `,"unknown":"program"`), + dir("h", "${machine:account-home}/.ssh", `,"unknown":"module"`))) + if found := check(t, root); len(found) != 0 { + t.Fatalf("refused %+v", found) + } +} + +func TestBadKnowsIsRefused(t *testing.T) { + for _, knows := range []string{`[""]`, `["/abs"]`, `["a/../b"]`, `["./a"]`, `["a//b"]`, `["a","a"]`, `["a","a/"]`} { + root := t.TempDir() + manifest(t, root, "a", mod("a", dir("d", "${machine:account-home}/.config/a", `,"unknown":"move-out","knows":`+knows))) + only(t, check(t, root), 3, "a", "d") + } + root := t.TempDir() + manifest(t, root, "a", mod("a", dir("d", "${machine:account-home}/.config/a", `,"unknown":"move-out","knows":["forge.credentials","kept/"]`))) + if found := check(t, root); len(found) != 0 { + t.Fatalf("refused %+v", found) + } +} + +func TestAnotherModulesPathInsideADirectoryIsRefused(t *testing.T) { + root := t.TempDir() + manifest(t, root, "owner", mod("owner", dir("ssh", "${machine:account-home}/.ssh", `,"unknown":"module"`))) + manifest(t, root, "intruder", mod("intruder", `{"id":"f","type":"file","path":"${machine:account-home}/.ssh/config.d/20"}`)) + manifest(t, root, "viahome", mod("viahome", `{"id":"g","type":"file","path":"${machine:agent-home}/.ssh/x"}`)) + manifest(t, root, "facty", `{"module":"facty","facts":{"hosts":{"path":".ssh/config.d/00","home":true}}}`) + manifest(t, root, "outside", mod("outside", `{"id":"o","type":"file","path":"${machine:account-home}/.sshrc"}`)) + got := map[string]int{} + for _, f := range check(t, root) { + if f.Rule != 4 || f.Why == "" { + t.Fatalf("finding %+v", f) + } + got[f.Module]++ + } + if len(got) != 3 || got["intruder"] != 1 || got["viahome"] != 1 || got["facty"] != 1 { + t.Fatalf("refused %v; want intruder, viahome, facty", got) + } +} + +func TestDirReferencesAreResolvedPerModule(t *testing.T) { + root := t.TempDir() + manifest(t, root, "owner", mod("owner", dir("base", "${machine:account-home}/.config/o", `,"unknown":"move-out"`))) + manifest(t, root, "other", mod("other", + dir("base", "${machine:account-home}/.config/p", `,"unknown":"move-out"`), + `{"id":"f","type":"file","path":"${dir:base}/x"}`)) + if found := check(t, root); len(found) != 0 { + t.Fatalf("refused %+v", found) + } + manifest(t, root, "third", mod("third", + dir("d", "${machine:account-home}/.config/t", `,"unknown":"move-out"`), + `{"id":"f","type":"file","path":"${dir:d}/../o/x"}`)) + only(t, check(t, root), 4, "third", "f") +} + +func TestAnArchiveIsNotAContainerAndSameModuleIsFine(t *testing.T) { + root := t.TempDir() + manifest(t, root, "a", mod("a", + `{"id":"arc","type":"archive","path":"/opt/a","unknown":"program"}`, + dir("d", "/opt/a2", `,"unknown":"program"`), + `{"id":"f","type":"file","path":"/opt/a2/x"}`)) + manifest(t, root, "b", mod("b", `{"id":"f","type":"file","path":"/opt/a/x"}`)) + if found := check(t, root); len(found) != 0 { + t.Fatalf("refused %+v", found) + } +} diff --git a/merge-check.sh b/merge-check.sh index 8afe1cc1..a466457d 100755 --- a/merge-check.sh +++ b/merge-check.sh @@ -45,8 +45,10 @@ # unless checks/templates/inline lists it as not yet moved; each names its template in files/. That list # only shrinks, judged against the trunk's copy at the merge base. # 10. the mail-store seat (novox/hq ADR 0378 §3, issue 800): no manifest but modules/mesh-mail claims it. -# 11. ~/.ssh (novox/hq ADR 0415 §6, issue 1020): no manifest but modules/ssh-client names a path under it — -# ssh-client owns it and sweeps out what it does not know. +# 11. owned paths (novox/hq ADR 0422 §8, issue 1024; it holds ~/.ssh for ssh-client as ADR 0415 §6 asked): +# every directory and archive says `unknown` (move-out, module or program) and a valid `knows`; `move-out` +# only under a home; and no module declares a path inside a directory of another module. +# checks/sshdir (ADR 0415 §6) stays while main runs it; it goes under issue 1035 once main runs checks/owned. set -eu (cd checks/words && go test -count=1 . && go run . ../..) @@ -54,8 +56,11 @@ set -eu (cd checks/agenthome && go test -count=1 . && go run . ../..) # The mail-store seat (novox/hq ADR 0378 §3): only mesh-mail may claim it. (cd checks/mailstore && go test -count=1 . && go run . ../..) -# ~/.ssh (novox/hq ADR 0415 §6): only ssh-client may name a path under it. +# ~/.ssh (novox/hq ADR 0415 §6): only ssh-client may name a path under it. Main's merge check runs this line, so +# checks/sshdir stays until main runs checks/owned; it goes under issue 1035. (cd checks/sshdir && go test -count=1 . && go run . ../..) +# Owned paths (novox/hq ADR 0422 §8): unknown files named per directory; no path inside another module's directory. +(cd checks/owned && go test -count=1 . && go run . ../..) # The secrets (novox/hq issue 342): a password is not a setting, so no setting can replace the vault's. The # known list only shrinks: judged against the trunk's copy at the merge base, a line it does not hold is refused. secrets_base="" diff --git a/modules/artifact-store-tools/README.md b/modules/artifact-store-tools/README.md index c337eefb..1b747f8f 100644 --- a/modules/artifact-store-tools/README.md +++ b/modules/artifact-store-tools/README.md @@ -109,3 +109,9 @@ store's current or an older name, a definition not read said first, escalation t tools served are exactly the manifest's `tools` and its `invokes` exactly the two controller verbs and the catalogue's two tools. Any command other than the two read-only scripts fails the test. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/artifact-store-tools/module.json b/modules/artifact-store-tools/module.json index fb6b34bb..208329cd 100644 --- a/modules/artifact-store-tools/module.json +++ b/modules/artifact-store-tools/module.json @@ -26,7 +26,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "store-names", diff --git a/modules/asus-zephyrus-g14/README.md b/modules/asus-zephyrus-g14/README.md index 05efa63c..aec3828d 100644 --- a/modules/asus-zephyrus-g14/README.md +++ b/modules/asus-zephyrus-g14/README.md @@ -385,3 +385,15 @@ The module no longer writes a file into i3's `config.d`. Its window-manager line under `files/i3/` where it had one) are a contribution to `node-display-session`. The i3 module places them in its own configuration under a `# ` line, so this module depends on a window manager being assigned beside it. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/usr/local/lib/asus-zephyrus-g14`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/systemd-suspend.service.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/systemd-hibernate.service.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/systemd-suspend-then-hibernate.service.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/nvidia-powerd.service.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/UPower/UPower.conf.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/X11/xorg.conf.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/asus-zephyrus-g14/module.json b/modules/asus-zephyrus-g14/module.json index 77869927..d1ee8d3b 100644 --- a/modules/asus-zephyrus-g14/module.json +++ b/modules/asus-zephyrus-g14/module.json @@ -54,7 +54,8 @@ "id": "scripts", "type": "archive", "path": "/usr/local/lib/asus-zephyrus-g14", - "artifact": "scripts" + "artifact": "scripts", + "unknown": "program" }, { "id": "nvidia-options", @@ -74,7 +75,8 @@ "id": "suspend-drop-ins", "type": "directory", "path": "/etc/systemd/system/systemd-suspend.service.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "nvidia-on-suspend", @@ -87,7 +89,8 @@ "id": "hibernate-drop-ins", "type": "directory", "path": "/etc/systemd/system/systemd-hibernate.service.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "nvidia-on-hibernate", @@ -100,7 +103,8 @@ "id": "suspend-then-hibernate-drop-ins", "type": "directory", "path": "/etc/systemd/system/systemd-suspend-then-hibernate.service.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "nvidia-on-suspend-then-hibernate", @@ -113,7 +117,8 @@ "id": "powerd-drop-ins", "type": "directory", "path": "/etc/systemd/system/nvidia-powerd.service.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "powerd-opt-in", @@ -146,7 +151,8 @@ "id": "upower-drop-ins", "type": "directory", "path": "/etc/UPower/UPower.conf.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "low-battery", @@ -169,7 +175,8 @@ "id": "xorg-drop-ins", "type": "directory", "path": "/etc/X11/xorg.conf.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "touchpad", diff --git a/modules/audit-logger/README.md b/modules/audit-logger/README.md new file mode 100644 index 00000000..76c1f690 --- /dev/null +++ b/modules/audit-logger/README.md @@ -0,0 +1,11 @@ +# audit-logger + +The `audit-logger` module of the mesh catalogue: declares directories on the node. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:trail}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:spool}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/audit-logger/module.json b/modules/audit-logger/module.json index 9f225050..122b94e7 100644 --- a/modules/audit-logger/module.json +++ b/modules/audit-logger/module.json @@ -47,17 +47,20 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "trail", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "spool", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" } ], "capabilities": [ diff --git a/modules/baserow/README.md b/modules/baserow/README.md new file mode 100644 index 00000000..a410bb65 --- /dev/null +++ b/modules/baserow/README.md @@ -0,0 +1,11 @@ +# baserow + +The `baserow` module of the mesh catalogue: runs the container image `baserow/baserow`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/baserow/module.json b/modules/baserow/module.json index e19568b6..81196218 100644 --- a/modules/baserow/module.json +++ b/modules/baserow/module.json @@ -71,19 +71,22 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "data", "type": "directory", "mode": "0755", - "owner": "9999:9999" + "owner": "9999:9999", + "unknown": "program" }, { "id": "server-env", diff --git a/modules/betterbird/README.md b/modules/betterbird/README.md index 628f32e3..bbc081d1 100644 --- a/modules/betterbird/README.md +++ b/modules/betterbird/README.md @@ -347,3 +347,14 @@ outside the mesh. With this version, a push to a node (each waits for the operat - The controller's `settings` verb, for every proposal and to read a layer as it stands; its `nodes` and `node` verbs, for which machines hold the module; and the module's own `betterbird_derive` on those machines (`invokes`). + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.config/betterbird`: holds only what this module declares and its own tools' records: `accounts-record.json` (`cmd/betterbird-tools/adoption.go:36`), `configuration-record.json` (`owned.go:33`) and the `kept/` folder of replaced filter files (`filters.go:261`); anything else is moved out by the node-engine to `~/.local/state/mesh-moved/betterbird/` with a list, never deleted (ADR 0422 §4). +- `/opt/betterbird`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/opt/betterbird/owl`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/opt/betterbird/distribution`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/opt/betterbird/defaults/pref`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/usr/local/lib/mesh-betterbird`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/betterbird/module.json b/modules/betterbird/module.json index 19319ef4..891f8832 100644 --- a/modules/betterbird/module.json +++ b/modules/betterbird/module.json @@ -83,7 +83,9 @@ "type": "directory", "path": "${machine:account-home}/.config/betterbird", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out", + "knows": ["accounts-record.json", "configuration-record.json", "kept/"] }, { "id": "prefs", @@ -150,31 +152,36 @@ "id": "installation", "type": "archive", "path": "/opt/betterbird", - "artifact": "archive" + "artifact": "archive", + "unknown": "program" }, { "id": "owl", "type": "archive", "path": "/opt/betterbird/owl", - "artifact": "owl" + "artifact": "owl", + "unknown": "program" }, { "id": "policies", "type": "archive", "path": "/opt/betterbird/distribution", - "artifact": "distribution" + "artifact": "distribution", + "unknown": "program" }, { "id": "spelling", "type": "archive", "path": "/opt/betterbird/defaults/pref", - "artifact": "defaults" + "artifact": "defaults", + "unknown": "program" }, { "id": "preparation", "type": "archive", "path": "/usr/local/lib/mesh-betterbird", - "artifact": "tools" + "artifact": "tools", + "unknown": "program" }, { "id": "start", diff --git a/modules/build-agent/README.md b/modules/build-agent/README.md index 7f253b8e..dab5632e 100644 --- a/modules/build-agent/README.md +++ b/modules/build-agent/README.md @@ -32,3 +32,11 @@ wins over it, and each build's log says which the build resolved from. A build t `package` artifact, an image whose Dockerfile names `.npmrc`, a TypeScript artifact with an `@novox/` dependency) on an agent with neither fails before building, naming the machine. Go artifacts and images that do not name `.npmrc` build without it. `manifest_test.go` holds the manifest to this. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:workspace}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:judge-cache}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/build-agent/module.json b/modules/build-agent/module.json index f9b789af..16c8753e 100644 --- a/modules/build-agent/module.json +++ b/modules/build-agent/module.json @@ -56,17 +56,20 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "workspace", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "judge-cache", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "agent-env", diff --git a/modules/ca-trust/README.md b/modules/ca-trust/README.md new file mode 100644 index 00000000..ea0b821a --- /dev/null +++ b/modules/ca-trust/README.md @@ -0,0 +1,9 @@ +# ca-trust + +The `ca-trust` module of the mesh catalogue: claims the seat `the-mesh-trust-anchor`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/ca-trust/module.json b/modules/ca-trust/module.json index 94e64fe4..b3c9dc93 100644 --- a/modules/ca-trust/module.json +++ b/modules/ca-trust/module.json @@ -25,7 +25,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "anchor", diff --git a/modules/claude-code/README.md b/modules/claude-code/README.md index c0423f3d..a02e88f9 100644 --- a/modules/claude-code/README.md +++ b/modules/claude-code/README.md @@ -10,10 +10,13 @@ Two directories, declared, so the mesh refuses a second module owning either: - `/etc/claude-code`, the agent's machine-wide managed directory, root's, `0755`. - `~/.claude` under the home of the account agents run as (the operator's, unless the machine names an agent account of its own), that account's, `0700`. The module owns the directory — - that it exists, who owns it, its mode — and of what is inside only what it writes. Everything else - in it (history, projects, local settings, a person's own rules and skills) is the person's - and is never read or written (hq ADR 0182) — but for each project's memory folder, which the module - carries between nodes (hq ADR 0343, below). Unassigned, the module leaves the directory: the host + that it exists, who owns it, its mode — and of what is inside only what it writes. What else is in + it (history, projects, local settings, a person's own rules and skills) is the person's, and the + directory is `unknown: module` (ADR 0422 §7): the module's own process decides what to do with a file + it did not write. Today that process carries each project's memory folder between nodes (hq ADR 0343, + below) and reads the home's items for its status tool; the reactions ADR 0273 decides (drift raised as a + condition, `home-copies`, unlisted entries raised) are not built yet (issue 1030), and until then nothing + else in it is moved. Unassigned, the module leaves the directory: the host removes a directory only when it is empty. And, for where the agent runs as an account of its own (hq ADR 0266): @@ -353,3 +356,11 @@ is written. The same sudo starts the helper as the agent's account, where there Go, one binary (`cmd/claude-code`) the node's runtime launches. Tested with `go test ./...`; the managed instruction file is held to the TypeScript renderer it replaced (`testdata/rendered-by-typescript.json`), and the sealed box is the licence manager's own format. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/etc/claude-code`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `~/.claude`: value `module` (ADR 0422 §7). The module's process carries each project's memory folder (ADR 0343) and reads the home's items for its status tool; nothing else in it is moved. The reactions ADR 0273 decides (drift raised as a condition, `home-copies`, unlisted entries raised) are not built yet (issue 1030). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/claude-code/module.json b/modules/claude-code/module.json index d6de675d..b869d012 100644 --- a/modules/claude-code/module.json +++ b/modules/claude-code/module.json @@ -154,7 +154,8 @@ "id": "managed", "type": "directory", "path": "/etc/claude-code", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "start", @@ -182,14 +183,16 @@ "type": "directory", "path": "${machine:agent-home}/.claude", "mode": "0700", - "owner": "${machine:agent-account}" + "owner": "${machine:agent-account}", + "unknown": "module" }, { "id": "state", "type": "directory", "mode": "0700", "owner": "${machine:account}", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "facts", diff --git a/modules/claude-licence-manager/README.md b/modules/claude-licence-manager/README.md index eb1f4064..58a984b3 100644 --- a/modules/claude-licence-manager/README.md +++ b/modules/claude-licence-manager/README.md @@ -53,3 +53,9 @@ Go one replaced, so the format is the one already on the machines. # the store against a real postgres: docker run -d --rm --name licmgr-pg -e POSTGRES_PASSWORD=t -p 15498:5432 postgres:16-alpine MESH_TEST_POSTGRES=postgres://postgres:t@127.0.0.1:15498/postgres go test ./... + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/claude-licence-manager/module.json b/modules/claude-licence-manager/module.json index a78a86fd..a55da31e 100644 --- a/modules/claude-licence-manager/module.json +++ b/modules/claude-licence-manager/module.json @@ -118,7 +118,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "database-url", diff --git a/modules/clipmenu/README.md b/modules/clipmenu/README.md index b9f504c9..9ae52091 100644 --- a/modules/clipmenu/README.md +++ b/modules/clipmenu/README.md @@ -93,3 +93,9 @@ The module no longer writes a file into i3's `config.d`. Its window-manager line under `files/i3/` where it had one) are a contribution to `node-display-session`. The i3 module places them in its own configuration under a `# ` line, so this module depends on a window manager being assigned beside it. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.config/systemd/user/clipmenud.service.d`: holds only what this module declares; anything else is moved out by the node-engine to `~/.local/state/mesh-moved/clipmenu/` with a list, never deleted (ADR 0422 §4). diff --git a/modules/clipmenu/module.json b/modules/clipmenu/module.json index f2d328f2..30ec9c0c 100644 --- a/modules/clipmenu/module.json +++ b/modules/clipmenu/module.json @@ -76,19 +76,13 @@ "mode": "0755", "template": "files/bin/xsel" }, - { - "id": "user-units-dir", - "type": "directory", - "path": "${machine:account-home}/.config/systemd/user", - "owner": "${machine:account}", - "mode": "0755" - }, { "id": "daemon-dropins", "type": "directory", "path": "${machine:account-home}/.config/systemd/user/clipmenud.service.d", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out" }, { "id": "daemon-dropin", diff --git a/modules/confluence/README.md b/modules/confluence/README.md new file mode 100644 index 00000000..b318407f --- /dev/null +++ b/modules/confluence/README.md @@ -0,0 +1,9 @@ +# confluence + +The `confluence` module of the mesh catalogue: declares directories on the node. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/confluence/module.json b/modules/confluence/module.json index 18fb5e5e..caa0d1be 100644 --- a/modules/confluence/module.json +++ b/modules/confluence/module.json @@ -24,7 +24,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "config", diff --git a/modules/desk-channel/README.md b/modules/desk-channel/README.md index 860ef98a..4579d995 100644 --- a/modules/desk-channel/README.md +++ b/modules/desk-channel/README.md @@ -55,3 +55,9 @@ each machine's notifier through the mesh: nothing new runs on the machines. | tool | does | |---|---| | `desk_channel_status` | whether it can show messages, the machines and each one's last answer, and its rules | + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/desk-channel/module.json b/modules/desk-channel/module.json index 3ee2dcc2..115ce620 100644 --- a/modules/desk-channel/module.json +++ b/modules/desk-channel/module.json @@ -66,7 +66,8 @@ "type": "directory", "mode": "0700", "owner": "desk-channel", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "settings", diff --git a/modules/distribution/README.md b/modules/distribution/README.md new file mode 100644 index 00000000..a7a90a38 --- /dev/null +++ b/modules/distribution/README.md @@ -0,0 +1,10 @@ +# distribution + +The `distribution` module of the mesh catalogue: runs the container image `registry`; claims the seat `mesh-artifact-store`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/var/lib/mesh/registry`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/mesh-registry`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/distribution/module.json b/modules/distribution/module.json index e368b824..eb9f7c24 100644 --- a/modules/distribution/module.json +++ b/modules/distribution/module.json @@ -50,13 +50,15 @@ "id": "state", "type": "directory", "path": "/var/lib/mesh/registry", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "registry-data", "type": "directory", "path": "/var/lib/mesh-registry", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "store", diff --git a/modules/dnsmasq/README.md b/modules/dnsmasq/README.md new file mode 100644 index 00000000..1fa0c2ce --- /dev/null +++ b/modules/dnsmasq/README.md @@ -0,0 +1,11 @@ +# dnsmasq + +The `dnsmasq` module of the mesh catalogue: installs the package `dnsmasq`; claims the seat `mesh-dns-resolver`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/dnsmasq.service.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/dnsmasq-watch`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/dnsmasq/module.json b/modules/dnsmasq/module.json index 1865d9b7..58cc0da5 100644 --- a/modules/dnsmasq/module.json +++ b/modules/dnsmasq/module.json @@ -58,7 +58,8 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "package", @@ -76,7 +77,8 @@ "id": "drop-ins", "type": "directory", "path": "/etc/systemd/system/dnsmasq.service.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "wait-for-address", @@ -105,7 +107,8 @@ "id": "watch-dir", "type": "directory", "path": "/var/lib/dnsmasq-watch", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "watch", diff --git a/modules/docker/README.md b/modules/docker/README.md index bc33c109..459fab7d 100644 --- a/modules/docker/README.md +++ b/modules/docker/README.md @@ -268,3 +268,9 @@ The tests run against a fake runner and cover: - event filtering; - volume ownership; - that the tools served are exactly the manifest's `tools`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/docker/module.json b/modules/docker/module.json index 80f0bed3..a3a75e09 100644 --- a/modules/docker/module.json +++ b/modules/docker/module.json @@ -83,7 +83,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "log-rotation", diff --git a/modules/dunst/README.md b/modules/dunst/README.md index c990dc4d..908d7cc5 100644 --- a/modules/dunst/README.md +++ b/modules/dunst/README.md @@ -6,8 +6,10 @@ The notifier as a module (novox/hq ADR 0208, research 026/05). The context menu its `dunstrc` calls is `rofi`, which the `rofi` module installs: two modules on one machine may not declare the same package, so a machine dunst serves also has `rofi` assigned. - Claims the mesh's `node-notifier` seat and serves its verbs `send` and `history`. -- Owns `~/.config/dunst/dunstrc` and the directory `~/.config/dunst/dunstrc.d/`. Another module's - rule is that module's own file in the directory (ADR 0208 §4). dunst reads the directory after +- Owns `~/.config/dunst/dunstrc` and the directory `~/.config/dunst/dunstrc.d/`. It holds what this + module declares and `50-slack.conf` (named in `knows`); any other file is moved out to + `~/.local/state/mesh-moved/dunst/` with a list, never deleted (ADR 0422). Another module's rule is that + module's own declared file in the directory (ADR 0208 §4). dunst reads the directory after `dunstrc`, so a drop-in outranks it. - **Starts nothing.** The package registers dunst with D-Bus, which starts it on the first notification, inside the account's service manager. There is no autostart line and no @@ -97,10 +99,10 @@ count. The file keeps only the settings that differ from dunst's defaults. - `icon_path`, which named two directories of an icon theme that is not installed, is gone. The icon theme is looked up recursively. -## What it leaves as found +## What it keeps -- `~/.config/dunst/dunstrc.d/50-slack.conf`, the Slack rule. It becomes the Slack module's own drop-in - when there is one, and until then it is the operator's file in a directory this module owns. +- `~/.config/dunst/dunstrc.d/50-slack.conf`, the Slack rule, named in `knows`: kept until its owner exists. + It becomes the Slack module's own drop-in when there is one. Any other file in the folder is moved out. ## Migration (ADR 0182) @@ -115,3 +117,10 @@ count. The file keeps only the settings that differ from dunst's defaults. unknown. - `dunst_rules` and the counts ask the running notifier. When none runs, the bus starts one, which needs a session to draw on. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.config/dunst`: holds only what this module declares; anything else is moved out by the node-engine to `~/.local/state/mesh-moved/dunst/` with a list, never deleted (ADR 0422 §4). +- `~/.config/dunst/dunstrc.d`: holds only what this module declares and `50-slack.conf` (the Slack rule, kept until its owner exists); anything else is moved out by the node-engine to `~/.local/state/mesh-moved/dunst/` with a list, never deleted (ADR 0422 §4). diff --git a/modules/dunst/module.json b/modules/dunst/module.json index fa4923db..0c6983b4 100644 --- a/modules/dunst/module.json +++ b/modules/dunst/module.json @@ -56,14 +56,17 @@ "type": "directory", "path": "${machine:account-home}/.config/dunst", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out" }, { "id": "dropins", "type": "directory", "path": "${machine:account-home}/.config/dunst/dunstrc.d", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out", + "knows": ["50-slack.conf"] }, { "id": "configuration", diff --git a/modules/fail2ban/README.md b/modules/fail2ban/README.md new file mode 100644 index 00000000..87fb505a --- /dev/null +++ b/modules/fail2ban/README.md @@ -0,0 +1,13 @@ +# fail2ban + +The `fail2ban` module of the mesh catalogue: installs the package `fail2ban`; claims the seat `node-intrusion-prevention`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/var/lib/mesh-fail2ban`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/fail2ban/jail.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/fail2ban/action.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/fail2ban/filter.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/run/fail2ban`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/fail2ban/module.json b/modules/fail2ban/module.json index d2aa2a65..446395f2 100644 --- a/modules/fail2ban/module.json +++ b/modules/fail2ban/module.json @@ -42,7 +42,8 @@ "id": "state-dir", "type": "directory", "path": "/var/lib/mesh-fail2ban", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "own-addresses-list", @@ -56,25 +57,29 @@ "id": "jail-d", "type": "directory", "path": "/etc/fail2ban/jail.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "action-d", "type": "directory", "path": "/etc/fail2ban/action.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "filter-d", "type": "directory", "path": "/etc/fail2ban/filter.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "run-dir", "type": "directory", "path": "/var/run/fail2ban", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "jail-local", diff --git a/modules/feh/README.md b/modules/feh/README.md index ea3140e3..72a19302 100644 --- a/modules/feh/README.md +++ b/modules/feh/README.md @@ -52,3 +52,9 @@ The module no longer writes a file into i3's `config.d`. Its window-manager line under `files/i3/` where it had one) are a contribution to `node-display-session`. The i3 module places them in its own configuration under a `# ` line, so this module depends on a window manager being assigned beside it. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.local/share/feh/wallpapers`: holds only what this module declares; anything else is moved out by the node-engine to `~/.local/state/mesh-moved/feh/` with a list, never deleted (ADR 0422 §4). diff --git a/modules/feh/module.json b/modules/feh/module.json index eb2c69bd..d6e44073 100644 --- a/modules/feh/module.json +++ b/modules/feh/module.json @@ -35,7 +35,8 @@ "type": "archive", "path": "${machine:account-home}/.local/share/feh/wallpapers", "owner": "${machine:account}", - "artifact": "wallpapers" + "artifact": "wallpapers", + "unknown": "move-out" }, { "id": "fehbg", diff --git a/modules/gitea/README.md b/modules/gitea/README.md index dca279c0..5592f0d6 100644 --- a/modules/gitea/README.md +++ b/modules/gitea/README.md @@ -233,3 +233,14 @@ and serves the entry values `user`, `ssh_host` (the forge machine's mesh name, f reported no key gets no entry, and its client says it waits. Keys titled `mesh:` that are no longer wanted are removed, a key added by hand never is. Every consumer is made again every ten minutes and at once when a key changes. `go test ./cmd/forge-account-provider ./internal/forgeaccount` runs it against a fake forge. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:mesh-state}/state`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/mesh/forge-patches`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/gitea/module.json b/modules/gitea/module.json index 324684eb..e8c73163 100644 --- a/modules/gitea/module.json +++ b/modules/gitea/module.json @@ -188,13 +188,15 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "runtime-state", "type": "directory", "path": "${dir:mesh-state}/state", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "ready-authors", @@ -209,18 +211,21 @@ "type": "directory", "path": "/var/lib/mesh/forge-patches", "mode": "0733", - "owner": "${machine:account}" + "owner": "${machine:account}", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "grants", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "server-env", @@ -233,7 +238,8 @@ "id": "data", "type": "directory", "mode": "0700", - "owner": "1000:1000" + "owner": "1000:1000", + "unknown": "program" }, { "id": "server", diff --git a/modules/gitlab/README.md b/modules/gitlab/README.md new file mode 100644 index 00000000..0d9db43d --- /dev/null +++ b/modules/gitlab/README.md @@ -0,0 +1,9 @@ +# gitlab + +The `gitlab` module of the mesh catalogue: declares directories on the node. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/gitlab/module.json b/modules/gitlab/module.json index 38be2014..3cb33fb2 100644 --- a/modules/gitlab/module.json +++ b/modules/gitlab/module.json @@ -17,7 +17,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "config", diff --git a/modules/grafana/README.md b/modules/grafana/README.md new file mode 100644 index 00000000..42877662 --- /dev/null +++ b/modules/grafana/README.md @@ -0,0 +1,13 @@ +# grafana + +The `grafana` module of the mesh catalogue: runs the container image `grafana/grafana`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}/datasources`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}/influxdb`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/grafana/module.json b/modules/grafana/module.json index 9d8ceebf..1cbf995f 100644 --- a/modules/grafana/module.json +++ b/modules/grafana/module.json @@ -48,19 +48,22 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "data", "type": "directory", "mode": "0700", - "owner": "472:472" + "owner": "472:472", + "unknown": "program" }, { "id": "admin-secret", @@ -90,14 +93,16 @@ "type": "directory", "path": "${dir:state}/datasources", "mode": "0755", - "owner": "472:472" + "owner": "472:472", + "unknown": "program" }, { "id": "influxdb-credential", "type": "directory", "path": "${dir:state}/influxdb", "mode": "0700", - "owner": "472:472" + "owner": "472:472", + "unknown": "program" }, { "id": "influxdb-secret", diff --git a/modules/hello-web/README.md b/modules/hello-web/README.md new file mode 100644 index 00000000..9b5f4499 --- /dev/null +++ b/modules/hello-web/README.md @@ -0,0 +1,9 @@ +# hello-web + +The `hello-web` module of the mesh catalogue: declares directories on the node. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/hello-web/module.json b/modules/hello-web/module.json index 44dfc471..005578cd 100644 --- a/modules/hello-web/module.json +++ b/modules/hello-web/module.json @@ -31,7 +31,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "page", diff --git a/modules/home-assistant/README.md b/modules/home-assistant/README.md new file mode 100644 index 00000000..34c2957f --- /dev/null +++ b/modules/home-assistant/README.md @@ -0,0 +1,12 @@ +# home-assistant + +The `home-assistant` module of the mesh catalogue: runs the container image `ghcr.io/home-assistant/home-assistant`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:config}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:written}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/home-assistant/module.json b/modules/home-assistant/module.json index 8aff932f..9c4f99db 100644 --- a/modules/home-assistant/module.json +++ b/modules/home-assistant/module.json @@ -58,23 +58,27 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "config", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "written", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "server", diff --git a/modules/i3/README.md b/modules/i3/README.md index 5903d847..ec5defdd 100644 --- a/modules/i3/README.md +++ b/modules/i3/README.md @@ -16,14 +16,14 @@ The window manager as a module (novox/hq ADR 0208, research 026, to-be 42 phase | path | class (ADR 0182) | what | |---|---|---| -| `~/.config/i3/` | owned directory | its contents other than `config` are found and kept | -| `~/.config/i3/config.d/` | owned directory | other modules' drop-ins, and yours | +| `~/.config/i3/` | owned directory (`move-out`) | what the module declares, and `scripts/` (named in `knows`: the screenshot binding in the main file runs `scripts/screenshot.sh`, kept until its owner exists); any other file is moved out by the node-engine to `~/.local/state/mesh-moved/i3/` with a list, never deleted (ADR 0422 §4) | +| `~/.config/i3/config.d/` | owned directory (`move-out`) | what the module declares, and `10-asus.conf` and `20-g14.conf` (named in `knows`, kept until the laptop's hardware module exists); any other file is moved out by the node-engine to `~/.local/state/mesh-moved/i3/` with a list, never deleted (ADR 0422 §4) | | `~/.config/i3/config` | owned (the found file kept once) | the main configuration, from [`files/config`](files/config) | | `/etc/lemurs/wms/i3` | owned | the login manager's session entry: `exec systemd-cat -t x-session /bin/sh "$HOME/.xinitrc"`, the session's output in the journal (`journalctl -t x-session`) because the login manager's pipe has no reader | -**Drop-ins.** Another module adds to i3 with its own `~/.config/i3/config.d/-.conf`. The -`include` is the last line of the main file, so every variable set there (`$mod`, `$ws1`…`$ws10`) is -in scope. Files are read in name order. A file of yours there is yours. +**Drop-ins.** `~/.config/i3/config.d/` holds what this module declares and the files named in `knows`; a +file of yours put there is moved out (ADR 0422). The `include` is the last line of the main file, so every +variable set there (`$mod`, `$ws1`…`$ws10`) is in scope. Files are read in name order. ## The reload watcher @@ -103,10 +103,13 @@ key. volume, the sessions launcher and the screenshot binding. Each leaves when the module that owns it is written. The peripherals' tray applet left it for the `polychromatic` module. -## What it leaves found +## What it keeps, and what it moves out -`~/.config/i3/scripts/`, `~/.config/i3/unlock-keyring.sh`, every file in `config.d/`, the -`/usr/share/xsessions` entries (the package's, no longer offered by `lemurs`), and i3's restart +Kept, because they work for the operator today: `~/.config/i3/scripts/` (the screenshot binding runs +`scripts/screenshot.sh`), and `config.d/10-asus.conf` and `20-g14.conf`, each until its owner exists. Both are +named in `knows`. Anything else in `~/.config/i3/` (such as `unlock-keyring.sh`) or in `config.d/` is moved +out by the node-engine to `~/.local/state/mesh-moved/i3/` with a list, never deleted (ADR 0422 §4). Left +alone, outside the folders: the `/usr/share/xsessions` entries (the package's, no longer offered by `lemurs`), and i3's restart state and logs. ## The one-off migration (ADR 0182) @@ -120,11 +123,11 @@ state and logs. module decides. 3. **Delete `/etc/lemurs/wms/i3wm`** (see `lemurs`). 4. **`config.d/` fragments:** - - `10-asus.conf` and `20-g14.conf` (the laptop) belong to that machine model's hardware module. - Keep them until it exists. The desktop no longer carries them. - - `50-slack.conf` (both) is yours, or a future `slack` module's. Keep it. - - `99-tmp-wine-focus.conf` (the desktop), a test of a predecessor change by its own comment: - **delete** it, or keep it as yours. + - `10-asus.conf` and `20-g14.conf` (the laptop) belong to that machine model's hardware module. They + are named in `knows`, so they stay until it exists. The desktop no longer carries them. + - `50-slack.conf` is not an i3 file: the Slack rule is dunst's (`dunstrc.d`, see `dunst`). + - `99-tmp-wine-focus.conf` (the desktop), a test of a predecessor change by its own comment, is moved + out at the first look with a list; nothing is lost. 5. **The main file's predecessor copy** is kept once by the host and written over. Nothing to do. ## What changes when it is assigned @@ -156,6 +159,13 @@ about to end, or accept it: a reload keeps every window and workspace. `node-display-session` receives `config` contributions, and this module places them with `${contribution:node-display-session:config}` near the end of its configuration, each module's -under a line naming it. `~/.config/i3/config.d/` is now the operator's alone: the include at the very +under a line naming it. `~/.config/i3/config.d/` holds only what is declared and named in `knows`: the include at the very end reads it after the mesh's lines. The catalogue-wide test composes every module's contribution as the controller does and checks the result with `i3 -C`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.config/i3`: holds only what this module declares and `scripts/` (the main file's screenshot binding runs `scripts/screenshot.sh`; kept until its owner exists); anything else is moved out by the node-engine to `~/.local/state/mesh-moved/i3/` with a list, never deleted (ADR 0422 §4). +- `~/.config/i3/config.d`: holds only what this module declares and `10-asus.conf`, `20-g14.conf` (the laptop's, kept until its hardware module exists); anything else is moved out by the node-engine to `~/.local/state/mesh-moved/i3/` with a list, never deleted (ADR 0422 §4). diff --git a/modules/i3/module.json b/modules/i3/module.json index 29fc3e85..1ec92426 100644 --- a/modules/i3/module.json +++ b/modules/i3/module.json @@ -72,14 +72,18 @@ "type": "directory", "path": "${machine:account-home}/.config/i3", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out", + "knows": ["scripts/"] }, { "id": "drop-ins", "type": "directory", "path": "${machine:account-home}/.config/i3/config.d", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out", + "knows": ["10-asus.conf", "20-g14.conf"] }, { "id": "config", diff --git a/modules/i3status-rust/README.md b/modules/i3status-rust/README.md index 8d3c9dda..77ca3cf8 100644 --- a/modules/i3status-rust/README.md +++ b/modules/i3status-rust/README.md @@ -80,9 +80,11 @@ a machine without the hardware, was rejected: the knowledge would stay in the ba other. It runs on both, once per session, and ends with the session. - The docker block's click, which ran a program installed on neither machine, is gone. -## What it leaves as found +## What it leaves, and what it moves out -- `~/.config/i3status-rust/scripts/` (a mouse battery script for one device). +- `~/.config/i3status-rust/scripts/` (a mouse battery script for one device) is not named in `knows`: the + bars do not use it, so the node-engine moves it out to `~/.local/state/mesh-moved/i3status-rust/` with a + list, never deleted (ADR 0422 §4). - `~/scripts/pkg-updates` and `~/scripts/i3-bar-watchdog`, replaced here. - The user unit `~/.config/systemd/user/i3-bar-watchdog.service` and its enablement link. @@ -112,3 +114,10 @@ The module no longer writes a file into i3's `config.d`. Its window-manager line under `files/i3/` where it had one) are a contribution to `node-display-session`. The i3 module places them in its own configuration under a `# ` line, so this module depends on a window manager being assigned beside it. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.config/i3status-rust`: holds only what this module declares; anything else is moved out by the node-engine to `~/.local/state/mesh-moved/i3status-rust/` with a list, never deleted (ADR 0422 §4). +- `~/.config/i3status-rust/icons`: holds only what this module declares; anything else is moved out by the node-engine to `~/.local/state/mesh-moved/i3status-rust/` with a list, never deleted (ADR 0422 §4). diff --git a/modules/i3status-rust/module.json b/modules/i3status-rust/module.json index 6704d0dc..1e07556b 100644 --- a/modules/i3status-rust/module.json +++ b/modules/i3status-rust/module.json @@ -43,14 +43,16 @@ "type": "directory", "path": "${machine:account-home}/.config/i3status-rust", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out" }, { "id": "icons-dir", "type": "directory", "path": "${machine:account-home}/.config/i3status-rust/icons", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out" }, { "id": "top-bar", diff --git a/modules/icecast/README.md b/modules/icecast/README.md new file mode 100644 index 00000000..1d2eabc4 --- /dev/null +++ b/modules/icecast/README.md @@ -0,0 +1,11 @@ +# icecast + +The `icecast` module of the mesh catalogue: runs the container image `infiniteproject/icecast`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:logs}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/icecast/module.json b/modules/icecast/module.json index f8288be7..6f9ab549 100644 --- a/modules/icecast/module.json +++ b/modules/icecast/module.json @@ -66,19 +66,22 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "logs", "type": "directory", "mode": "0700", - "owner": "100:101" + "owner": "100:101", + "unknown": "program" }, { "id": "server-conf", diff --git a/modules/influxdb/README.md b/modules/influxdb/README.md new file mode 100644 index 00000000..f021b6a5 --- /dev/null +++ b/modules/influxdb/README.md @@ -0,0 +1,13 @@ +# influxdb + +The `influxdb` module of the mesh catalogue: runs the container image `influxdb`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:config}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/influxdb/module.json b/modules/influxdb/module.json index 2d73b8d7..53389a5f 100644 --- a/modules/influxdb/module.json +++ b/modules/influxdb/module.json @@ -88,30 +88,35 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "data", "type": "directory", "mode": "0700", - "owner": "1000:1000" + "owner": "1000:1000", + "unknown": "program" }, { "id": "config", "type": "directory", "mode": "0700", - "owner": "1000:1000" + "owner": "1000:1000", + "unknown": "program" }, { "id": "grants", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "server-env", diff --git a/modules/invoicing/README.md b/modules/invoicing/README.md new file mode 100644 index 00000000..b86e33c1 --- /dev/null +++ b/modules/invoicing/README.md @@ -0,0 +1,10 @@ +# invoicing + +The `invoicing` module of the mesh catalogue: runs the container image `registry-api.novox.be/novox/invoicing-app`; runs the container image `registry-api.novox.be/novox/invoicing-api`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/invoicing/module.json b/modules/invoicing/module.json index 5b846d1c..29670a3e 100644 --- a/modules/invoicing/module.json +++ b/modules/invoicing/module.json @@ -55,13 +55,15 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "api-env", diff --git a/modules/jira/README.md b/modules/jira/README.md new file mode 100644 index 00000000..21f19b2a --- /dev/null +++ b/modules/jira/README.md @@ -0,0 +1,9 @@ +# jira + +The `jira` module of the mesh catalogue: declares directories on the node. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/jira/module.json b/modules/jira/module.json index eceb279d..9f98dd83 100644 --- a/modules/jira/module.json +++ b/modules/jira/module.json @@ -23,7 +23,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "config", diff --git a/modules/kernel/README.md b/modules/kernel/README.md index 09405354..6acb6a37 100644 --- a/modules/kernel/README.md +++ b/modules/kernel/README.md @@ -50,3 +50,9 @@ rotates the journal once and not for `always` nor while the machine starts, goes reload without rewriting what it found, gives back what it found and then keeps nothing, refuses a value the kernel does not take before writing anything, fails when the write does not take, and says when the kernel has no transparent huge pages. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/kernel/module.json b/modules/kernel/module.json index 7305c945..67d32156 100644 --- a/modules/kernel/module.json +++ b/modules/kernel/module.json @@ -20,7 +20,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "huge-pages", diff --git a/modules/keycloak/README.md b/modules/keycloak/README.md index e786fc09..925e00de 100644 --- a/modules/keycloak/README.md +++ b/modules/keycloak/README.md @@ -83,3 +83,11 @@ capability. `live_test.go` runs the repair against a real, throwaway Keycloak 26 container whose admin keeps an older password. The file's comment has the commands. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/keycloak/module.json b/modules/keycloak/module.json index 03749aa6..847d5f4f 100644 --- a/modules/keycloak/module.json +++ b/modules/keycloak/module.json @@ -116,18 +116,21 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "grants", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "consumers", diff --git a/modules/lab/README.md b/modules/lab/README.md new file mode 100644 index 00000000..17db440e --- /dev/null +++ b/modules/lab/README.md @@ -0,0 +1,10 @@ +# lab + +The `lab` module of the mesh catalogue: installs the package `git`; installs the package `make`; installs the package `python`; installs the package `file`; installs the package `iproute2`; installs the package `npm`; installs the package `go`; installs the package `incus`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/mesh-lab-runs`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/lab/module.json b/modules/lab/module.json index 66bb4b43..e23963df 100644 --- a/modules/lab/module.json +++ b/modules/lab/module.json @@ -42,13 +42,15 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "work", "type": "directory", "path": "/var/lib/mesh-lab-runs", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "runtime-env", diff --git a/modules/lemurs/README.md b/modules/lemurs/README.md index ebe732b3..17e2e34a 100644 --- a/modules/lemurs/README.md +++ b/modules/lemurs/README.md @@ -109,3 +109,10 @@ merges the X resources before any long-lived client connects. On the first login the server reset twice within four seconds: the X log showed three server generations. xterm fell back to the bitmap `fixed` font, without the mesh's face and colours. lemurs reads its configuration when it starts, so the change applies after the next boot. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/etc/lemurs/xsessions`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/lemurs/wayland-sessions`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/lemurs/module.json b/modules/lemurs/module.json index abaf8b11..702a9596 100644 --- a/modules/lemurs/module.json +++ b/modules/lemurs/module.json @@ -43,13 +43,15 @@ "id": "xsessions", "type": "directory", "path": "/etc/lemurs/xsessions", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "wayland-sessions", "type": "directory", "path": "/etc/lemurs/wayland-sessions", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "service", diff --git a/modules/letta/README.md b/modules/letta/README.md new file mode 100644 index 00000000..ee4af0ff --- /dev/null +++ b/modules/letta/README.md @@ -0,0 +1,10 @@ +# letta + +The `letta` module of the mesh catalogue: runs the container image `letta/letta`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/letta/module.json b/modules/letta/module.json index dbcc5590..de7baf64 100644 --- a/modules/letta/module.json +++ b/modules/letta/module.json @@ -60,13 +60,15 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "server-env", diff --git a/modules/local-model-consumer/README.md b/modules/local-model-consumer/README.md new file mode 100644 index 00000000..38255e61 --- /dev/null +++ b/modules/local-model-consumer/README.md @@ -0,0 +1,10 @@ +# local-model-consumer + +The `local-model-consumer` module of the mesh catalogue: declares directories on the node. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:config}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/local-model-consumer/module.json b/modules/local-model-consumer/module.json index 6fdb90b5..73002092 100644 --- a/modules/local-model-consumer/module.json +++ b/modules/local-model-consumer/module.json @@ -13,12 +13,14 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "config", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "openai-env", diff --git a/modules/mailu/README.md b/modules/mailu/README.md index ba5d3443..e87c4f61 100644 --- a/modules/mailu/README.md +++ b/modules/mailu/README.md @@ -15,3 +15,28 @@ installation's are settings on the assignment, `settings set mailu `: `website` are shown by the web front; `proxy-address` is what `REAL_IP_FROM` trusts a real-IP header from — the address the proxy forwards with. The front's own hostname is the name of its `web` route, told to it by the mesh. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-automx}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-certs}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-dkim}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-mail}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-mailqueue}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-filter}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-clamav}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-redis}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-webmail}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-dav}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-fetchmail}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-overrides-nginx}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-overrides-dovecot}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-overrides-postfix}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-overrides-rspamd}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data-overrides-roundcube}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mailu/module.json b/modules/mailu/module.json index 52750c98..568be145 100644 --- a/modules/mailu/module.json +++ b/modules/mailu/module.json @@ -291,23 +291,27 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "grants", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-automx", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "config-env", @@ -340,82 +344,98 @@ { "id": "data-certs", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-data", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-dkim", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-mail", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-mailqueue", "type": "directory", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "data-filter", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-clamav", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-redis", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-webmail", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-dav", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-fetchmail", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-overrides-nginx", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-overrides-dovecot", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-overrides-postfix", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-overrides-rspamd", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data-overrides-roundcube", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "net", diff --git a/modules/marrytts/README.md b/modules/marrytts/README.md new file mode 100644 index 00000000..1bf579d0 --- /dev/null +++ b/modules/marrytts/README.md @@ -0,0 +1,9 @@ +# marrytts + +The `marrytts` module of the mesh catalogue: runs the container image `synesthesiam/marytts`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/marrytts/module.json b/modules/marrytts/module.json index bd12abfa..ed242aa3 100644 --- a/modules/marrytts/module.json +++ b/modules/marrytts/module.json @@ -18,7 +18,8 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "server", diff --git a/modules/matrix/README.md b/modules/matrix/README.md new file mode 100644 index 00000000..7e513bb1 --- /dev/null +++ b/modules/matrix/README.md @@ -0,0 +1,10 @@ +# matrix + +The `matrix` module of the mesh catalogue: runs the container image `matrixconduit/matrix-conduit`; runs the container image `vectorim/element-web`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:db}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/matrix/module.json b/modules/matrix/module.json index 2c044576..170719cc 100644 --- a/modules/matrix/module.json +++ b/modules/matrix/module.json @@ -160,12 +160,14 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "db", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "conduit-conf", diff --git a/modules/memory-pressure/README.md b/modules/memory-pressure/README.md index 8c4d0c75..ee76aecc 100644 --- a/modules/memory-pressure/README.md +++ b/modules/memory-pressure/README.md @@ -118,3 +118,12 @@ zram statistics and PSI lines. They cover: - `since` refused when it is an option; - *no match* read as no kills; - the manifest: tools listed equal tools served, events, no machine named, triggers exist. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/etc/sysctl.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/oomd.conf.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/-.slice.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/user@.service.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/memory-pressure/module.json b/modules/memory-pressure/module.json index 76ae53be..1af96e30 100644 --- a/modules/memory-pressure/module.json +++ b/modules/memory-pressure/module.json @@ -34,7 +34,8 @@ "id": "sysctl-drop-ins", "type": "directory", "path": "/etc/sysctl.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "swap-tunables", @@ -55,7 +56,8 @@ "id": "oomd-drop-ins", "type": "directory", "path": "/etc/systemd/oomd.conf.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "oomd-limits", @@ -68,7 +70,8 @@ "id": "root-slice-drop-ins", "type": "directory", "path": "/etc/systemd/system/-.slice.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "root-slice", @@ -81,7 +84,8 @@ "id": "user-manager-drop-ins", "type": "directory", "path": "/etc/systemd/system/user@.service.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "user-manager", diff --git a/modules/mesh-catalog/README.md b/modules/mesh-catalog/README.md new file mode 100644 index 00000000..32e34d2f --- /dev/null +++ b/modules/mesh-catalog/README.md @@ -0,0 +1,9 @@ +# mesh-catalog + +The `mesh-catalog` module of the mesh catalogue: claims the seat `mesh-catalog`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-catalog/module.json b/modules/mesh-catalog/module.json index 5a263800..8d8c6599 100644 --- a/modules/mesh-catalog/module.json +++ b/modules/mesh-catalog/module.json @@ -41,7 +41,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "database-url", diff --git a/modules/mesh-cli/README.md b/modules/mesh-cli/README.md index 6dfb4cab..74f2387f 100644 --- a/modules/mesh-cli/README.md +++ b/modules/mesh-cli/README.md @@ -62,3 +62,9 @@ operator. alone); the line is asked as given and the answer printed with its exit; a reason, a refusal, a cut and an outcome not known are said and a refusal never exits 0; a verb's process is refused before asking; an engine that does not answer is said. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/usr/local/bin`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-cli/module.json b/modules/mesh-cli/module.json index a72f91ac..681a3e55 100644 --- a/modules/mesh-cli/module.json +++ b/modules/mesh-cli/module.json @@ -7,7 +7,8 @@ "id": "program", "type": "archive", "artifact": "program", - "path": "/usr/local/bin" + "path": "/usr/local/bin", + "unknown": "program" } ], "items": [ diff --git a/modules/mesh-config/README.md b/modules/mesh-config/README.md index 7a9ab019..b8ac192f 100644 --- a/modules/mesh-config/README.md +++ b/modules/mesh-config/README.md @@ -50,3 +50,9 @@ and sets nothing, when the proposal or the value stored at the level changed sin value as a set does, keeps who approved it beside the value (`approved`), and asks the controller to record the warrant in its hand-act log. A Decline, an expiry or the router's refusal sets nothing. `action` `proposals` lists them, newest first; with `proposal`, one read whole, with whether the router's ask is the one composed from it. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-config/module.json b/modules/mesh-config/module.json index 9665b54c..e03e891b 100644 --- a/modules/mesh-config/module.json +++ b/modules/mesh-config/module.json @@ -52,7 +52,8 @@ "type": "directory", "mode": "0700", "owner": "mesh-config", - "place": "." + "place": ".", + "unknown": "program" } ], "build": { diff --git a/modules/mesh-delivery/README.md b/modules/mesh-delivery/README.md new file mode 100644 index 00000000..18b78dcb --- /dev/null +++ b/modules/mesh-delivery/README.md @@ -0,0 +1,9 @@ +# mesh-delivery + +The `mesh-delivery` module of the mesh catalogue: claims the seat `mesh-delivery`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-delivery/module.json b/modules/mesh-delivery/module.json index 80f1cc49..7a445a3a 100644 --- a/modules/mesh-delivery/module.json +++ b/modules/mesh-delivery/module.json @@ -76,7 +76,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" } ], "build": { diff --git a/modules/mesh-files/README.md b/modules/mesh-files/README.md index f844592b..b2e49215 100644 --- a/modules/mesh-files/README.md +++ b/modules/mesh-files/README.md @@ -61,3 +61,9 @@ an override the override and the owned paths it went through. The caller is the name for `read`, `list` and `search`. Copying or moving such a place is allowed: nothing is printed. - A copy or move to or from `:/path` is refused: copying between nodes comes in step 2 (issue 903). - A write without a reason; a path that is not absolute; a mode that is not a mode. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-files/module.json b/modules/mesh-files/module.json index 867222a3..cc1df162 100644 --- a/modules/mesh-files/module.json +++ b/modules/mesh-files/module.json @@ -32,7 +32,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" } ], "build": { diff --git a/modules/mesh-issues/README.md b/modules/mesh-issues/README.md index 33287bf0..865dda67 100644 --- a/modules/mesh-issues/README.md +++ b/modules/mesh-issues/README.md @@ -421,3 +421,9 @@ the carry carrying each value kept, oldest first, once, passing over a deletion write to an issue the bucket kept before the switch carries its three kept values first, read through the runtime's history. Over the bus, the stream the controller makes holds one operation per change of `TestAnIssueIsOpenedNotedLinkedMovedAndListedOverTheBus`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-issues/module.json b/modules/mesh-issues/module.json index e911c2b1..94e047d3 100644 --- a/modules/mesh-issues/module.json +++ b/modules/mesh-issues/module.json @@ -287,7 +287,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "settings", diff --git a/modules/mesh-knowledge/README.md b/modules/mesh-knowledge/README.md index 8bef489d..7cb938b1 100644 --- a/modules/mesh-knowledge/README.md +++ b/modules/mesh-knowledge/README.md @@ -235,3 +235,9 @@ listening on no port. A machine with neither skips the postgres half and says so `testdata/hq` holds eleven records at the commit in its `COMMIT` file, and `testdata/hq-main.tar.gz` holds the whole of main at `testdata/hq-main.commit`. The bus test starts the bundle as the runtime does and plays the runtime over a real NATS server. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-knowledge/module.json b/modules/mesh-knowledge/module.json index 261662be..c57687b6 100644 --- a/modules/mesh-knowledge/module.json +++ b/modules/mesh-knowledge/module.json @@ -100,7 +100,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "database-url", diff --git a/modules/mesh-mail-notifier/README.md b/modules/mesh-mail-notifier/README.md index 9891e96b..29f8a720 100644 --- a/modules/mesh-mail-notifier/README.md +++ b/modules/mesh-mail-notifier/README.md @@ -38,3 +38,9 @@ accounts it announces, in mesh-mail's trusted setting `grants` (`mail-store`'s s |---|---| | `mail-notifier.status` | every account it is granted, when it last showed each one a notice, and any notice still failing to send (its count, last error, since when). Read-only | | `mail_notifier_health` | how it is: unhealthy once a notice has failed to show for more than ten minutes, healthy otherwise, even mid-retry. Not (yet) the node-engine's own check — this is one process, judged only by its own tool (ADR 0227 rule 8); a watching process of its own is issue 841, not yet decided. Read-only | + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-mail-notifier/module.json b/modules/mesh-mail-notifier/module.json index dec4d77a..9afba466 100644 --- a/modules/mesh-mail-notifier/module.json +++ b/modules/mesh-mail-notifier/module.json @@ -46,7 +46,8 @@ "type": "directory", "mode": "0700", "owner": "mesh-mail-notifier", - "place": "." + "place": ".", + "unknown": "program" } ], "build": { diff --git a/modules/mesh-mail/README.md b/modules/mesh-mail/README.md index 51d133d9..f7b77338 100644 --- a/modules/mesh-mail/README.md +++ b/modules/mesh-mail/README.md @@ -79,3 +79,9 @@ above — the same grants, the same refusals, the same ask-then-Approve for a se `prepare` brings the index's schema to this version's (numbered migrations, and `schema.sql` for a fresh database). `keep` watches the accounts and is judged by its unit. `watch` judges every minute and is judged by `mail_health`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-mail/module.json b/modules/mesh-mail/module.json index ae445990..38a5ccea 100644 --- a/modules/mesh-mail/module.json +++ b/modules/mesh-mail/module.json @@ -103,7 +103,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "database-url", diff --git a/modules/mesh-provisioner-client/README.md b/modules/mesh-provisioner-client/README.md index 62c1ec4c..da3bae5b 100644 --- a/modules/mesh-provisioner-client/README.md +++ b/modules/mesh-provisioner-client/README.md @@ -86,3 +86,9 @@ module in the tool runner reads its secrets from its files. A binding's non-secr into files (issue 679) and not yet answered on an ask. It says on `prov.changed..` which value moved (`{kind, key}`, every key of the kind when `key` is absent, never the value), when the client starts and on every change, so the tool runner asks again for the watches it holds. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-provisioner-client/module.json b/modules/mesh-provisioner-client/module.json index af84e540..095128a8 100644 --- a/modules/mesh-provisioner-client/module.json +++ b/modules/mesh-provisioner-client/module.json @@ -24,7 +24,8 @@ "type": "directory", "mode": "0700", "owner": "mesh-provisioner-client", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "client", diff --git a/modules/mesh-provisioner/README.md b/modules/mesh-provisioner/README.md index 88c246b3..383d216e 100644 --- a/modules/mesh-provisioner/README.md +++ b/modules/mesh-provisioner/README.md @@ -31,3 +31,9 @@ reads the needs without writing them. This module writes only the registry. `mesh-provisioner.provisioning` with `what` `registry` (the default), `needs`, `applied` or `collect`, narrowed by `node` and `module` (for `collect`, the contributor) and, for `collect`, `collection`. Reads only. A key out of its bucket's shape is said in the answer, never dropped quietly. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-provisioner/module.json b/modules/mesh-provisioner/module.json index 11133aef..650425b3 100644 --- a/modules/mesh-provisioner/module.json +++ b/modules/mesh-provisioner/module.json @@ -34,7 +34,8 @@ "type": "directory", "mode": "0700", "owner": "mesh-provisioner", - "place": "." + "place": ".", + "unknown": "program" } ], "build": { diff --git a/modules/mesh-reads/README.md b/modules/mesh-reads/README.md index 2981bdc3..5112a9b0 100644 --- a/modules/mesh-reads/README.md +++ b/modules/mesh-reads/README.md @@ -61,3 +61,9 @@ token. | `account` | `getent passwd`, `getent group`, `id`, `groups` | 2000 accounts and groups; never a password field | No answer is larger than 1 MiB. Nothing here writes a file. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-reads/module.json b/modules/mesh-reads/module.json index 4a664485..18062752 100644 --- a/modules/mesh-reads/module.json +++ b/modules/mesh-reads/module.json @@ -33,7 +33,8 @@ "type": "directory", "mode": "0700", "owner": "mesh-reads", - "place": "." + "place": ".", + "unknown": "program" } ], "build": { diff --git a/modules/mesh-vault/README.md b/modules/mesh-vault/README.md index d51bdd7a..429b861a 100644 --- a/modules/mesh-vault/README.md +++ b/modules/mesh-vault/README.md @@ -277,3 +277,13 @@ the vault answers it (recorded before the prompt, one open ask per secret and th the bus named it, the typed value opened only here), the issuing provider's test with a stand-in provider (ADR 0305 §13's checks that belong to the vault: nothing rewritten for a value held, `rotate` refused, no other way in), and accept and rotate. `followups_test.go` holds V1's review follow-ups. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:ledger}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:root}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:store}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-vault/module.json b/modules/mesh-vault/module.json index 83ee6cd4..44944c95 100644 --- a/modules/mesh-vault/module.json +++ b/modules/mesh-vault/module.json @@ -86,31 +86,36 @@ "type": "directory", "mode": "0700", "owner": "mesh-vault", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "grants", "type": "directory", "mode": "0700", - "owner": "mesh-vault" + "owner": "mesh-vault", + "unknown": "program" }, { "id": "ledger", "type": "directory", "mode": "0700", - "owner": "mesh-vault" + "owner": "mesh-vault", + "unknown": "program" }, { "id": "root", "type": "directory", "mode": "0700", - "owner": "mesh-vault" + "owner": "mesh-vault", + "unknown": "program" }, { "id": "store", "type": "directory", "mode": "0700", - "owner": "mesh-vault" + "owner": "mesh-vault", + "unknown": "program" } ], "build": { diff --git a/modules/mesh-watcher/README.md b/modules/mesh-watcher/README.md index d311fa82..f107520e 100644 --- a/modules/mesh-watcher/README.md +++ b/modules/mesh-watcher/README.md @@ -36,3 +36,9 @@ when the parts that would tell them are what failed. | `watcher_last_heard` | when each signal was last heard, and what it sent lately | | `watcher_test` | a test message to Telegram now, directly | | `watcher_ping` | the bus round trip's other end | + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mesh-watcher/module.json b/modules/mesh-watcher/module.json index 798fcf20..e9543a5d 100644 --- a/modules/mesh-watcher/module.json +++ b/modules/mesh-watcher/module.json @@ -31,7 +31,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "settings", diff --git a/modules/messenger/README.md b/modules/messenger/README.md index 10b86afd..5a5a26ba 100644 --- a/modules/messenger/README.md +++ b/modules/messenger/README.md @@ -253,3 +253,9 @@ runtime-carried module's are). It holds no secret. until the runtime takes a seat's queue for a bundle (mesh-tools). - **Channels are inside the holder**, not modules contributing to the seat: a seat a module declares cannot receive contributions yet (ADR 0212 kinds are compiled for the mesh's own seats). + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/messenger/module.json b/modules/messenger/module.json index 89d0b3a6..7af1c177 100644 --- a/modules/messenger/module.json +++ b/modules/messenger/module.json @@ -145,7 +145,8 @@ "type": "directory", "mode": "0700", "place": ".", - "owner": "messenger" + "owner": "messenger", + "unknown": "program" }, { "id": "settings", diff --git a/modules/minio/README.md b/modules/minio/README.md new file mode 100644 index 00000000..44447bd1 --- /dev/null +++ b/modules/minio/README.md @@ -0,0 +1,11 @@ +# minio + +The `minio` module of the mesh catalogue: runs the container image `docker.io/pgsty/minio`; installs the package `minio-client`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/minio-store`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/minio/module.json b/modules/minio/module.json index fd59501e..85b82530 100644 --- a/modules/minio/module.json +++ b/modules/minio/module.json @@ -92,12 +92,14 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "grants", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "root-env", @@ -110,7 +112,8 @@ "id": "data", "type": "directory", "path": "/var/lib/minio-store", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "net", diff --git a/modules/model-usage/README.md b/modules/model-usage/README.md new file mode 100644 index 00000000..732b149f --- /dev/null +++ b/modules/model-usage/README.md @@ -0,0 +1,10 @@ +# model-usage + +The `model-usage` module of the mesh catalogue: declares directories on the node. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:spool}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/model-usage/module.json b/modules/model-usage/module.json index 0ab5703d..50743a3c 100644 --- a/modules/model-usage/module.json +++ b/modules/model-usage/module.json @@ -43,7 +43,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "database-url", @@ -55,7 +56,8 @@ { "id": "spool", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "prepare", diff --git a/modules/mongodb/README.md b/modules/mongodb/README.md new file mode 100644 index 00000000..12d9e3ef --- /dev/null +++ b/modules/mongodb/README.md @@ -0,0 +1,12 @@ +# mongodb + +The `mongodb` module of the mesh catalogue: runs the container image `mongo`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:dumps}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mongodb/module.json b/modules/mongodb/module.json index de9d9105..cbb12681 100644 --- a/modules/mongodb/module.json +++ b/modules/mongodb/module.json @@ -81,22 +81,26 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "grants", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "dumps", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "net", diff --git a/modules/mosquitto/README.md b/modules/mosquitto/README.md new file mode 100644 index 00000000..9b7c4682 --- /dev/null +++ b/modules/mosquitto/README.md @@ -0,0 +1,12 @@ +# mosquitto + +The `mosquitto` module of the mesh catalogue: runs the container image `eclipse-mosquitto`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mosquitto/module.json b/modules/mosquitto/module.json index e9cb913c..21058e0a 100644 --- a/modules/mosquitto/module.json +++ b/modules/mosquitto/module.json @@ -78,24 +78,28 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "grants", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data", "type": "directory", "mode": "0700", - "owner": "1883:1883" + "owner": "1883:1883", + "unknown": "program" }, { "id": "server-conf", diff --git a/modules/mounts/README.md b/modules/mounts/README.md index 65cac223..83f72dd8 100644 --- a/modules/mounts/README.md +++ b/modules/mounts/README.md @@ -210,3 +210,12 @@ The tools run as the operator account and act as root through `sudo -n`. The `su account every command, so **this module's code is the only line** between a tool call and root: each act checks again what it may touch before it runs a command, and a test holds each check. Narrowing what sudo grants the account to the commands these modules need is a separate decision, not made here. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/mesh-mounts`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/mesh-mounts`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/mesh-mounts/from-bus`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mounts/module.json b/modules/mounts/module.json index 9424dc1c..488ebb97 100644 --- a/modules/mounts/module.json +++ b/modules/mounts/module.json @@ -73,13 +73,15 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "config-dir", "type": "directory", "path": "/etc/mesh-mounts", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "config", @@ -92,14 +94,16 @@ "id": "bus-dir-parent", "type": "directory", "path": "/var/lib/mesh-mounts", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "bus-dir", "type": "directory", "path": "/var/lib/mesh-mounts/from-bus", "mode": "0755", - "owner": "${machine:account}" + "owner": "${machine:account}", + "unknown": "program" }, { "id": "apply", diff --git a/modules/mssql/README.md b/modules/mssql/README.md new file mode 100644 index 00000000..899cac99 --- /dev/null +++ b/modules/mssql/README.md @@ -0,0 +1,12 @@ +# mssql + +The `mssql` module of the mesh catalogue: runs the container image `mcr.microsoft.com/mssql/server`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}/backup`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/mssql/module.json b/modules/mssql/module.json index e30276c9..ed4e4488 100644 --- a/modules/mssql/module.json +++ b/modules/mssql/module.json @@ -80,12 +80,14 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "grants", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "sa-env", @@ -98,14 +100,16 @@ "id": "data", "type": "directory", "mode": "0700", - "owner": "10001:0" + "owner": "10001:0", + "unknown": "program" }, { "id": "dumps", "type": "directory", "path": "${dir:data}/backup", "mode": "0700", - "owner": "10001:0" + "owner": "10001:0", + "unknown": "program" }, { "id": "net", diff --git a/modules/n8n/README.md b/modules/n8n/README.md new file mode 100644 index 00000000..c911c864 --- /dev/null +++ b/modules/n8n/README.md @@ -0,0 +1,11 @@ +# n8n + +The `n8n` module of the mesh catalogue: runs the container image `redis`; runs the container image `selenium/standalone-chrome`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:cache}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/n8n/module.json b/modules/n8n/module.json index 23874b61..975247fa 100644 --- a/modules/n8n/module.json +++ b/modules/n8n/module.json @@ -60,19 +60,22 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "data", "type": "directory", "mode": "0700", - "owner": "1000:1000" + "owner": "1000:1000", + "unknown": "program" }, { "id": "cache", "type": "directory", "mode": "0700", - "owner": "999:999" + "owner": "999:999", + "unknown": "program" }, { "id": "database-secret", diff --git a/modules/nats/README.md b/modules/nats/README.md index f07245fa..c9d3c046 100644 --- a/modules/nats/README.md +++ b/modules/nats/README.md @@ -85,3 +85,12 @@ reads (`nats stream restore ` on an unpacked `streams//`). `MESH_TEST_NATS_IMAGE=` also runs the manifest's declared dump, exactly, against the module's image and configuration. - `cmd/nats-tools`: `go test ./...`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/var/lib/mesh-broker-nats`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/nats-module/conf`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:snapshots}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/nats/module.json b/modules/nats/module.json index 3c633473..3ad66bc3 100644 --- a/modules/nats/module.json +++ b/modules/nats/module.json @@ -75,24 +75,28 @@ "id": "jetstream-data", "type": "directory", "path": "/var/lib/mesh-broker-nats", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "conf-dir", "type": "directory", "path": "/var/lib/nats-module/conf", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "snapshots", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "server-conf", diff --git a/modules/nextcloud/README.md b/modules/nextcloud/README.md new file mode 100644 index 00000000..366d7d89 --- /dev/null +++ b/modules/nextcloud/README.md @@ -0,0 +1,11 @@ +# nextcloud + +The `nextcloud` module of the mesh catalogue: runs the container image `nextcloud`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:html}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/nextcloud/module.json b/modules/nextcloud/module.json index c7d32627..2854a160 100644 --- a/modules/nextcloud/module.json +++ b/modules/nextcloud/module.json @@ -79,13 +79,15 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "server-env", @@ -98,7 +100,8 @@ "id": "html", "type": "directory", "mode": "0750", - "owner": "33:33" + "owner": "33:33", + "unknown": "program" }, { "id": "server", diff --git a/modules/nfs-server/README.md b/modules/nfs-server/README.md index 3c17f47a..ab6488d7 100644 --- a/modules/nfs-server/README.md +++ b/modules/nfs-server/README.md @@ -153,3 +153,12 @@ The tools run as the operator account and act as root through `sudo -n`. The `su account every command, so **this module's code is the only line** between a tool call and root: each act checks again what it may touch before it runs a command, and a test holds each check. Narrowing what sudo grants the account to the commands these modules need is a separate decision, not made here. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/run/nfs-server`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/nfs-server`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/nfs-server/from-bus`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/nfs-server`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/nfs-server/module.json b/modules/nfs-server/module.json index 70b7f924..f9994d16 100644 --- a/modules/nfs-server/module.json +++ b/modules/nfs-server/module.json @@ -101,7 +101,8 @@ "id": "run-dir", "type": "directory", "path": "/run/nfs-server", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "server", @@ -120,14 +121,16 @@ "id": "wants-dir-parent", "type": "directory", "path": "/var/lib/nfs-server", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "wants-dir", "type": "directory", "path": "/var/lib/nfs-server/from-bus", "mode": "0755", - "owner": "${machine:account}" + "owner": "${machine:account}", + "unknown": "program" }, { "id": "exports", @@ -154,7 +157,8 @@ "id": "config-dir", "type": "directory", "path": "/etc/nfs-server", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "config", diff --git a/modules/node-env/README.md b/modules/node-env/README.md new file mode 100644 index 00000000..4a6bce13 --- /dev/null +++ b/modules/node-env/README.md @@ -0,0 +1,10 @@ +# node-env + +The `node-env` module of the mesh catalogue: claims the seat `node-environment`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.config/mesh`: holds only what this module declares and `forge.credentials`, which claude-code's process places in the agent's home (issue 1033); anything else is moved out by the node-engine to `~/.local/state/mesh-moved/node-env/` with a list, never deleted (ADR 0422 §4). +- `~/.config/environment.d`: holds only what this module declares; anything else is moved out by the node-engine to `~/.local/state/mesh-moved/node-env/` with a list, never deleted (ADR 0422 §4). diff --git a/modules/node-env/module.json b/modules/node-env/module.json index a933578c..85fd7e57 100644 --- a/modules/node-env/module.json +++ b/modules/node-env/module.json @@ -14,14 +14,17 @@ "type": "directory", "path": "${machine:account-home}/.config/mesh", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out", + "knows": ["forge.credentials"] }, { "id": "environment-d", "type": "directory", "path": "${machine:account-home}/.config/environment.d", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out" }, { "id": "posix", diff --git a/modules/nodered/README.md b/modules/nodered/README.md new file mode 100644 index 00000000..763aa722 --- /dev/null +++ b/modules/nodered/README.md @@ -0,0 +1,12 @@ +# nodered + +The `nodered` module of the mesh catalogue: runs the container image `nodered/node-red`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:written}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/nodered/module.json b/modules/nodered/module.json index 48c65dd0..f8068dd1 100644 --- a/modules/nodered/module.json +++ b/modules/nodered/module.json @@ -143,24 +143,28 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "data", "type": "directory", "mode": "0700", - "owner": "1000:1000" + "owner": "1000:1000", + "unknown": "program" }, { "id": "written", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "settings-code", diff --git a/modules/ollama/README.md b/modules/ollama/README.md new file mode 100644 index 00000000..efe7b645 --- /dev/null +++ b/modules/ollama/README.md @@ -0,0 +1,9 @@ +# ollama + +The `ollama` module of the mesh catalogue: runs the container image `ollama/ollama`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/services/ollama`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/ollama/module.json b/modules/ollama/module.json index 2291c632..2d5fb48c 100644 --- a/modules/ollama/module.json +++ b/modules/ollama/module.json @@ -42,7 +42,8 @@ "id": "state", "type": "directory", "path": "/services/ollama", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "server", diff --git a/modules/only-office/README.md b/modules/only-office/README.md new file mode 100644 index 00000000..3129fc4b --- /dev/null +++ b/modules/only-office/README.md @@ -0,0 +1,16 @@ +# only-office + +The `only-office` module of the mesh catalogue: runs the container image `onlyoffice/documentserver`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:logs}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:lib}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:db}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:rabbitmq}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:redis}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:fonts}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/only-office/module.json b/modules/only-office/module.json index ac0eed75..4af651f4 100644 --- a/modules/only-office/module.json +++ b/modules/only-office/module.json @@ -80,7 +80,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "server-env", @@ -92,37 +93,44 @@ { "id": "logs", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "lib", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "db", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "rabbitmq", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "redis", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "fonts", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "net", diff --git a/modules/openai-consumer/README.md b/modules/openai-consumer/README.md new file mode 100644 index 00000000..45272519 --- /dev/null +++ b/modules/openai-consumer/README.md @@ -0,0 +1,10 @@ +# openai-consumer + +The `openai-consumer` module of the mesh catalogue: declares directories on the node. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:config}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/openai-consumer/module.json b/modules/openai-consumer/module.json index 90457d98..2e98414e 100644 --- a/modules/openai-consumer/module.json +++ b/modules/openai-consumer/module.json @@ -19,12 +19,14 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "config", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "apply", diff --git a/modules/photos-eef/README.md b/modules/photos-eef/README.md new file mode 100644 index 00000000..d27db20a --- /dev/null +++ b/modules/photos-eef/README.md @@ -0,0 +1,9 @@ +# photos-eef + +The `photos-eef` module of the mesh catalogue: runs the container image `registry-api.novox.be/novox/photos-client`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/photos-eef/module.json b/modules/photos-eef/module.json index 0ab336b8..101bdc27 100644 --- a/modules/photos-eef/module.json +++ b/modules/photos-eef/module.json @@ -31,7 +31,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "net", diff --git a/modules/photos-filip/README.md b/modules/photos-filip/README.md new file mode 100644 index 00000000..7d8bd12d --- /dev/null +++ b/modules/photos-filip/README.md @@ -0,0 +1,9 @@ +# photos-filip + +The `photos-filip` module of the mesh catalogue: runs the container image `registry-api.novox.be/novox/photos-client`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/photos-filip/module.json b/modules/photos-filip/module.json index 518012f8..9c1c83fa 100644 --- a/modules/photos-filip/module.json +++ b/modules/photos-filip/module.json @@ -31,7 +31,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "net", diff --git a/modules/picom/README.md b/modules/picom/README.md index be9a79ba..54e3408b 100644 --- a/modules/picom/README.md +++ b/modules/picom/README.md @@ -59,7 +59,7 @@ A picom a tool starts runs under the account's own service manager (`systemd-run in place. It probably fails to start on that machine's GPU. `picom_restart` with `hard` after assignment answers with what happened. The next step is the `picom` user unit's journal. -## What it leaves as found +## What lies outside its directory The window manager's own `exec --no-startup-id picom` line belongs to the `i3` module's configuration, which no longer carries it. Nothing else of picom's lies outside the directory this module owns. @@ -78,3 +78,9 @@ which no longer carries it. Nothing else of picom's lies outside the directory t the module. - `xorg-xprop` is declared here because the `xorg` module does not install it. If `xorg` comes to declare it, it leaves this module, since a package is declared once per node. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.config/picom`: holds only what this module declares; anything else is moved out by the node-engine to `~/.local/state/mesh-moved/picom/` with a list, never deleted (ADR 0422 §4). diff --git a/modules/picom/module.json b/modules/picom/module.json index 2f747784..cfdc3970 100644 --- a/modules/picom/module.json +++ b/modules/picom/module.json @@ -55,7 +55,8 @@ "type": "directory", "path": "${machine:account-home}/.config/picom", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out" }, { "id": "configuration", diff --git a/modules/postgres/README.md b/modules/postgres/README.md index 10a9ad2e..be777275 100644 --- a/modules/postgres/README.md +++ b/modules/postgres/README.md @@ -114,3 +114,12 @@ retired login locked out with its data kept and listed retired, enabled again as dropping only its own database and role. `live_reader_test.go` and `readable_live_test.go` need no extension: an install's reader as issue 337 found it reading no secret after its first query, and the reconcile granting exactly what is declared, refusing secrets, taking back what is no longer declared, and finding a grant to `PUBLIC`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/mesh-store`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:store-data}/dumps`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/postgres/module.json b/modules/postgres/module.json index 934c2ef4..919df421 100644 --- a/modules/postgres/module.json +++ b/modules/postgres/module.json @@ -96,12 +96,14 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "grants", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "consumers", @@ -115,14 +117,16 @@ "type": "directory", "path": "/var/lib/mesh-store", "mode": "0700", - "owner": "999:70" + "owner": "999:70", + "unknown": "program" }, { "id": "dumps", "type": "directory", "path": "${dir:store-data}/dumps", "mode": "0700", - "owner": "999:70" + "owner": "999:70", + "unknown": "program" }, { "id": "server", diff --git a/modules/power/README.md b/modules/power/README.md index e353aaa0..b23268f5 100644 --- a/modules/power/README.md +++ b/modules/power/README.md @@ -132,3 +132,18 @@ its three siblings) — the same way the laptop module asks for the NVIDIA drive **polkit is this module's package.** logind gives a delay lock to a process that is not root only through polkit. A server without polkit refused the watcher with "Permission denied", and its sleeps and shutdowns would have gone unsaid. The module installs it; nothing else needed it there. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/usr/local/lib/mesh-power`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/mesh-power`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/mesh-power/moments`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/logind.conf.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/sleep.target.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/suspend.target.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/hibernate.target.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/hybrid-sleep.target.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/systemd/system/suspend-then-hibernate.target.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/run/mesh-power`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/power/module.json b/modules/power/module.json index cea72ad7..a110d410 100644 --- a/modules/power/module.json +++ b/modules/power/module.json @@ -128,19 +128,22 @@ "id": "scripts", "type": "archive", "path": "/usr/local/lib/mesh-power", - "artifact": "scripts" + "artifact": "scripts", + "unknown": "program" }, { "id": "config-dir", "type": "directory", "path": "/etc/mesh-power", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "moments-dir", "type": "directory", "path": "/etc/mesh-power/moments", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "moment-after-boot", @@ -188,7 +191,8 @@ "id": "logind-drop-ins", "type": "directory", "path": "/etc/systemd/logind.conf.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "logind-power", @@ -244,7 +248,8 @@ "id": "sleep-drop-ins", "type": "directory", "path": "/etc/systemd/system/sleep.target.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "sleep-wants", @@ -257,7 +262,8 @@ "id": "suspend-drop-ins", "type": "directory", "path": "/etc/systemd/system/suspend.target.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "suspend-wants", @@ -270,7 +276,8 @@ "id": "hibernate-drop-ins", "type": "directory", "path": "/etc/systemd/system/hibernate.target.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "hibernate-wants", @@ -283,7 +290,8 @@ "id": "hybrid-sleep-drop-ins", "type": "directory", "path": "/etc/systemd/system/hybrid-sleep.target.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "hybrid-sleep-wants", @@ -296,7 +304,8 @@ "id": "suspend-then-hibernate-drop-ins", "type": "directory", "path": "/etc/systemd/system/suspend-then-hibernate.target.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "suspend-then-hibernate-wants", @@ -330,7 +339,8 @@ "id": "draw-dir", "type": "directory", "path": "/run/mesh-power", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "draw", diff --git a/modules/powerlevel10k/README.md b/modules/powerlevel10k/README.md index b6d8e07b..3a2d2a5d 100644 --- a/modules/powerlevel10k/README.md +++ b/modules/powerlevel10k/README.md @@ -21,6 +21,9 @@ release's contents, and update the version here and in the shell code's comment. | `~/.local/share/powerlevel10k/` | the theme, unpacked from the `theme` archive | owned, whole | | `~/.config/powerlevel10k/p10k.zsh` | the prompt's configuration, unpacked from the `configuration` archive | owned, whole | +Both directories are `unknown: move-out` (ADR 0422): they hold only what the archives declare, and anything +else found in them is moved out by the node-engine, never deleted. + The configuration is today's `~/.p10k.zsh`, byte for byte. It is the predecessor's file, and was identical on every machine. It ships as an archive of one file rather than as an inline file. At 86 KB, inline content would ride in every declaration the node receives, and would be unreadable @@ -44,3 +47,10 @@ operator's `.zshrc` has its cache line commented out today, and the configuratio - **Moving from the predecessor:** once this module is assigned, `~/.zsh/themes/powerlevel10k` and `~/.p10k.zsh` are no longer read, and the operator removes them, once (ADR 0182; the zsh module's README lists the lines to delete from `.zshrc`). + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.local/share/powerlevel10k`: holds only what this module declares and the nine `.zwc` files the theme compiles into its own folder at every zsh start (`powerlevel9k.zsh-theme.zwc`, `powerlevel10k.zsh-theme.zwc`, `internal/{p10k,icons,configure,worker,parser}.zsh.zwc`, `gitstatus/gitstatus.plugin.zsh.zwc`, `gitstatus/install.zwc`; `powerlevel10k.zsh-theme` lines 62-70); anything else is moved out by the node-engine to `~/.local/state/mesh-moved/powerlevel10k/` with a list, never deleted (ADR 0422 §4). +- `~/.config/powerlevel10k`: holds only what this module declares; anything else is moved out by the node-engine to `~/.local/state/mesh-moved/powerlevel10k/` with a list, never deleted (ADR 0422 §4). diff --git a/modules/powerlevel10k/module.json b/modules/powerlevel10k/module.json index 39d2810d..da1bd4df 100644 --- a/modules/powerlevel10k/module.json +++ b/modules/powerlevel10k/module.json @@ -8,14 +8,17 @@ "type": "archive", "path": "${machine:account-home}/.local/share/powerlevel10k", "owner": "${machine:account}", - "artifact": "theme" + "artifact": "theme", + "unknown": "move-out", + "knows": ["powerlevel9k.zsh-theme.zwc", "powerlevel10k.zsh-theme.zwc", "internal/p10k.zsh.zwc", "internal/icons.zsh.zwc", "internal/configure.zsh.zwc", "internal/worker.zsh.zwc", "internal/parser.zsh.zwc", "gitstatus/gitstatus.plugin.zsh.zwc", "gitstatus/install.zwc"] }, { "id": "configuration", "type": "archive", "path": "${machine:account-home}/.config/powerlevel10k", "owner": "${machine:account}", - "artifact": "configuration" + "artifact": "configuration", + "unknown": "move-out" } ], "items": [ diff --git a/modules/powerlevel10k/test/module.test.ts b/modules/powerlevel10k/test/module.test.ts index e9bc8522..9f8d7829 100644 --- a/modules/powerlevel10k/test/module.test.ts +++ b/modules/powerlevel10k/test/module.test.ts @@ -22,8 +22,8 @@ test("the configuration archive holds the prompt's configuration and nothing els test("both are unpacked under the account's home, owned by the account", () => { const byId = Object.fromEntries(m.resources.map((r: { id: string }) => [r.id, r])); - assert.deepEqual(byId.theme, { id: "theme", type: "archive", path: "${machine:account-home}/.local/share/powerlevel10k", owner: "${machine:account}", artifact: "theme" }); - assert.deepEqual(byId.configuration, { id: "configuration", type: "archive", path: "${machine:account-home}/.config/powerlevel10k", owner: "${machine:account}", artifact: "configuration" }); + assert.deepEqual(byId.theme, { id: "theme", type: "archive", path: "${machine:account-home}/.local/share/powerlevel10k", owner: "${machine:account}", artifact: "theme", unknown: "move-out", knows: ["powerlevel9k.zsh-theme.zwc", "powerlevel10k.zsh-theme.zwc", "internal/p10k.zsh.zwc", "internal/icons.zsh.zwc", "internal/configure.zsh.zwc", "internal/worker.zsh.zwc", "internal/parser.zsh.zwc", "gitstatus/gitstatus.plugin.zsh.zwc", "gitstatus/install.zwc"] }); + assert.deepEqual(byId.configuration, { id: "configuration", type: "archive", path: "${machine:account-home}/.config/powerlevel10k", owner: "${machine:account}", artifact: "configuration", unknown: "move-out" }); }); // The zsh code is an item of the collection shell:zsh:normal, its text a template in files/ (ADR 0348, 0349). diff --git a/modules/records/README.md b/modules/records/README.md index 9854e316..6fb679cd 100644 --- a/modules/records/README.md +++ b/modules/records/README.md @@ -49,3 +49,10 @@ layout cloned into the given directory itself, from a container running as root, operator account cannot change; git then refused every sync as "dubious ownership" (hq issue 251). What that layout left is removed where it is the module's, and named in `records_status` (`leftBehind`, with the one command that deletes it) where it is not. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:checkout}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/records/module.json b/modules/records/module.json index 9fcf22f5..db6f7e5a 100644 --- a/modules/records/module.json +++ b/modules/records/module.json @@ -43,13 +43,15 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "checkout", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "config", diff --git a/modules/redis/README.md b/modules/redis/README.md new file mode 100644 index 00000000..9a2c8af2 --- /dev/null +++ b/modules/redis/README.md @@ -0,0 +1,11 @@ +# redis + +The `redis` module of the mesh catalogue: runs the container image `redis`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/redis/module.json b/modules/redis/module.json index fc67a289..58e11064 100644 --- a/modules/redis/module.json +++ b/modules/redis/module.json @@ -68,18 +68,21 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "grants", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "data", "type": "directory", "mode": "0700", - "owner": "999:1000" + "owner": "999:1000", + "unknown": "program" }, { "id": "server-conf", diff --git a/modules/restic/README.md b/modules/restic/README.md index 9bdaedf0..1ec851b8 100644 --- a/modules/restic/README.md +++ b/modules/restic/README.md @@ -21,3 +21,10 @@ Against mistakes, not disasters: nothing leaves the machine. `node-backup.backed-up` lists each module's restore points taken by hand under `handTaken`: when each was taken, the time it is kept at least until, whether it still waits for a later good night, and a sentence saying so. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:repository}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/restic/module.json b/modules/restic/module.json index e7089278..18ee811d 100644 --- a/modules/restic/module.json +++ b/modules/restic/module.json @@ -77,12 +77,14 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "repository", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "declared", diff --git a/modules/rofi/README.md b/modules/rofi/README.md index b83197c3..f9bdab20 100644 --- a/modules/rofi/README.md +++ b/modules/rofi/README.md @@ -70,9 +70,10 @@ A Wayland session gets the same menu from whichever launcher holds the seat ther - `icon-theme` and `window-command` are gone. They named an icon theme and a program (`wmctrl`) that nothing installs. rofi's defaults serve. -## What it leaves as found +## What it moves out -- `~/.config/rofi/themes-repo/` (a cloned theme repository), the five symbolic links into it +- Moved out by the node-engine to `~/.local/state/mesh-moved/rofi/` with a list, never deleted (ADR 0422 §4), + because no `knows` names them: `~/.config/rofi/themes-repo/` (a cloned theme repository), the five symbolic links into it (`applets`, `images`, `launchers`, `powermenu`, `scripts`), `colors/`, `theme.rasi` and `powermenu.rasi`. - The predecessor's scripts in `~/scripts`: `rofi-launcher-normal`, `rofi-launcher-terminal`, @@ -83,8 +84,9 @@ A Wayland session gets the same menu from whichever launcher holds the seat ther Once the `i3` module carries the main i3 configuration: -1. Delete `~/.config/rofi/theme.rasi`, `powermenu.rasi`, `colors/`, the five links and `themes-repo/`. - Nothing reads them any more. +1. `~/.config/rofi/theme.rasi`, `powermenu.rasi`, `colors/`, the five links and `themes-repo/` are moved + out for you (with a list, in `~/.local/state/mesh-moved/rofi/`). Nothing reads them any more; delete the + moved copies when you like. 2. Delete the four scripts above from `~/scripts`. 3. Your scripts that call `rofi -dmenu` keep working. Calling `dmenu` instead lets them follow the seat, for example to a Wayland launcher later. @@ -102,3 +104,10 @@ The module no longer writes a file into i3's `config.d`. Its window-manager line under `files/i3/` where it had one) are a contribution to `node-display-session`. The i3 module places them in its own configuration under a `# ` line, so this module depends on a window manager being assigned beside it. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.config/rofi`: holds only what this module declares; anything else is moved out by the node-engine to `~/.local/state/mesh-moved/rofi/` with a list, never deleted (ADR 0422 §4). +- `~/.config/rofi/themes`: holds only what this module declares; anything else is moved out by the node-engine to `~/.local/state/mesh-moved/rofi/` with a list, never deleted (ADR 0422 §4). diff --git a/modules/rofi/module.json b/modules/rofi/module.json index 1cc9b2ff..fbd061d0 100644 --- a/modules/rofi/module.json +++ b/modules/rofi/module.json @@ -34,14 +34,16 @@ "type": "directory", "path": "${machine:account-home}/.config/rofi", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out" }, { "id": "themes-dir", "type": "directory", "path": "${machine:account-home}/.config/rofi/themes", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out" }, { "id": "configuration", diff --git a/modules/route-adapter/README.md b/modules/route-adapter/README.md index d71d3975..d7cd2abc 100644 --- a/modules/route-adapter/README.md +++ b/modules/route-adapter/README.md @@ -179,3 +179,10 @@ provider helper for `route`, with no credential. A consumer of a route whose tem (a handed gitea's origins file) is filled by its machine's client from this module's entry for it. The entry's values are the names the controller composed for that consumer, carried in its plan and copied unchanged: the public domain is placement, so only the controller can join a label to it. The adapter still writes the predecessor proxy's files. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/route-adapter/routes`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/route-adapter/module.json b/modules/route-adapter/module.json index 0f2f37d2..5234c78b 100644 --- a/modules/route-adapter/module.json +++ b/modules/route-adapter/module.json @@ -58,13 +58,15 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "routes-dir", "type": "directory", "path": "/var/lib/route-adapter/routes", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "config", diff --git a/modules/route-proxy/README.md b/modules/route-proxy/README.md index 5b167dfe..5fea89a1 100644 --- a/modules/route-proxy/README.md +++ b/modules/route-proxy/README.md @@ -91,3 +91,13 @@ A small Go program beside the proxy (`cmd/route-provider`) runs the SDK's provid and the offer says `"answered-by": "helper"`: a handed consumer (gitea's origins file) is filled by its machine's client from this module's entry, which carries the public names the controller composed for it. The module is **not** marked moved: its own files, `acme.env` and the broker secret, are composed as before, and the proxy itself is unchanged. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/route-proxy/routes`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/route-proxy/acme`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/route-proxy/ca`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/route-proxy/cmd/route-provider/provider_test.go b/modules/route-proxy/cmd/route-provider/provider_test.go index d7ccaffc..79a01405 100644 --- a/modules/route-proxy/cmd/route-provider/provider_test.go +++ b/modules/route-proxy/cmd/route-provider/provider_test.go @@ -102,7 +102,7 @@ func TestRouteProxyIsNotMovedAndKeepsItsOwnFiles(t *testing.T) { t.Fatal(err) } sum := sha256.Sum256(pinned) - if got := hex.EncodeToString(sum[:]); got != "57a39de0943d8b33b9db6cb998ce97f8793602cca6cdfa5849c1c392390454a3" { + if got := hex.EncodeToString(sum[:]); got != "7e6b3a1721ccf89c042c41b77940a3b31f7632fa19e627f83fe1a65bc9a57ab1" { t.Fatalf("route-proxy's own manifest changed: digest %s", got) } // The two acme templates are pinned the same way (issue 849): they are what the proxy's certificates are asked diff --git a/modules/route-proxy/module.json b/modules/route-proxy/module.json index a2734f17..4534774a 100644 --- a/modules/route-proxy/module.json +++ b/modules/route-proxy/module.json @@ -65,31 +65,36 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "routes-dir", "type": "directory", "path": "/var/lib/route-proxy/routes", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "acme-cache", "type": "directory", "path": "/var/lib/route-proxy/acme", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "ca-dir", "type": "directory", "path": "/var/lib/route-proxy/ca", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "acme-env", diff --git a/modules/searxng/README.md b/modules/searxng/README.md new file mode 100644 index 00000000..6b28bbca --- /dev/null +++ b/modules/searxng/README.md @@ -0,0 +1,11 @@ +# searxng + +The `searxng` module of the mesh catalogue: runs the container image `valkey/valkey`; runs the container image `searxng/searxng`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:valkey-data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/searxng/module.json b/modules/searxng/module.json index 01d40126..cee18e4e 100644 --- a/modules/searxng/module.json +++ b/modules/searxng/module.json @@ -107,18 +107,21 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "valkey-data", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "net", diff --git a/modules/showcase/README.md b/modules/showcase/README.md new file mode 100644 index 00000000..e37d5141 --- /dev/null +++ b/modules/showcase/README.md @@ -0,0 +1,11 @@ +# showcase + +The `showcase` module of the mesh catalogue: installs the package `jq`; claims the seat `the-showcase`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/opt/showcase`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/showcase/module.json b/modules/showcase/module.json index 9f9e9812..e657e2ab 100644 --- a/modules/showcase/module.json +++ b/modules/showcase/module.json @@ -101,13 +101,15 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0755", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "settings", @@ -120,7 +122,8 @@ "id": "packed", "type": "archive", "path": "/opt/showcase", - "artifact": "files" + "artifact": "files", + "unknown": "program" }, { "id": "net", diff --git a/modules/ssh-client/README.md b/modules/ssh-client/README.md index 301cd579..c6a42861 100644 --- a/modules/ssh-client/README.md +++ b/modules/ssh-client/README.md @@ -83,7 +83,7 @@ ADR 0417 (issue 1020) adds: `ssh_client_check` reports a failed last sweep, and a listed move with nothing at its destination, as a problem. -No other module declares a path under `~/.ssh` (ADR 0415 §6): the catalogue's `checks/sshdir` fails one +No other module declares a path under `~/.ssh` (ADR 0415 §6): the catalogue's `checks/owned` (ADR 0422 §8) fails one that does. So the predecessor's `config.d/mesh`, `config.bak-*`, `known_hosts.old`, `removed-*` and @@ -132,3 +132,10 @@ The tests use a temporary home and a fake runner, with public keys made for the itself), what it moves, what it leaves and names, a file being written, another file system, and the list written before each move; - that the tools served are the manifest's `tools`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.ssh`: the module's own sweep moves everything it does not know into a kept folder, listing each move first and failing loudly when one cannot be made (ADR 0415, ADR 0417); value `module` (ADR 0422 §3). +- `~/.ssh/config.d`: the same sweep covers it; value `module` (ADR 0415, ADR 0417). diff --git a/modules/ssh-client/cmd/ssh-client-tools/templates_test.go b/modules/ssh-client/cmd/ssh-client-tools/templates_test.go index 4b8be920..ccadfd09 100644 --- a/modules/ssh-client/cmd/ssh-client-tools/templates_test.go +++ b/modules/ssh-client/cmd/ssh-client-tools/templates_test.go @@ -156,7 +156,6 @@ func TestForgeFilesRenderFromTheBoundValues(t *testing.T) { t.Errorf("10-forge = %q, want %q", got, want) } - resourceByPath(t, home+"/.config/git") // the directory g := resourceByPath(t, home+"/.config/git/config") if g["into"] != "block" { t.Errorf("git config is %v, want a block", g["into"]) diff --git a/modules/ssh-client/module.json b/modules/ssh-client/module.json index d4780c2f..a6965445 100644 --- a/modules/ssh-client/module.json +++ b/modules/ssh-client/module.json @@ -34,14 +34,16 @@ "type": "directory", "path": "${machine:account-home}/.ssh", "owner": "${machine:account}", - "mode": "0700" + "mode": "0700", + "unknown": "module" }, { "id": "config-d", "type": "directory", "path": "${machine:account-home}/.ssh/config.d", "owner": "${machine:account}", - "mode": "0700" + "mode": "0700", + "unknown": "module" }, { "id": "config", @@ -70,13 +72,6 @@ "mode": "0600", "template": "files/forge" }, - { - "id": "git-config-dir", - "type": "directory", - "path": "${machine:account-home}/.config/git", - "owner": "${machine:account}", - "mode": "0755" - }, { "id": "git-config", "type": "file", diff --git a/modules/step-ca/README.md b/modules/step-ca/README.md new file mode 100644 index 00000000..455ee1e7 --- /dev/null +++ b/modules/step-ca/README.md @@ -0,0 +1,10 @@ +# step-ca + +The `step-ca` module of the mesh catalogue: runs the container image `smallstep/step-ca`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:home}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/step-ca/module.json b/modules/step-ca/module.json index ebb587db..b11d2b99 100644 --- a/modules/step-ca/module.json +++ b/modules/step-ca/module.json @@ -43,14 +43,16 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "home", "type": "directory", "mode": "0700", "owner": "1000:1000", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "config", diff --git a/modules/supabase/README.md b/modules/supabase/README.md new file mode 100644 index 00000000..eafb0cae --- /dev/null +++ b/modules/supabase/README.md @@ -0,0 +1,16 @@ +# supabase + +The `supabase` module of the mesh catalogue: runs the container image `timberio/vector`; runs the container image `supabase/postgres`; runs the container image `supabase/logflare`; runs the container image `kong`; runs the container image `supabase/gotrue`; runs the container image `postgrest/postgrest`; runs the container image `supabase/realtime`; runs the container image `darthsim/imgproxy`; runs the container image `supabase/storage-api`; runs the container image `supabase/postgres-meta`; runs the container image `supabase/edge-runtime`; runs the container image `supabase/studio`; runs the container image `supabase/supavisor`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}/db-init`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}/functions-main`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:db-data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}/dumps`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:db-config}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:storage}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:functions}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/supabase/module.json b/modules/supabase/module.json index 2ae3515c..14ddbcd5 100644 --- a/modules/supabase/module.json +++ b/modules/supabase/module.json @@ -113,47 +113,55 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "db-init", "type": "directory", "path": "${dir:state}/db-init", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "functions-main-dir", "type": "directory", "path": "${dir:state}/functions-main", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "db-data", "type": "directory", "mode": "0700", - "owner": "105:106" + "owner": "105:106", + "unknown": "program" }, { "id": "dumps", "type": "directory", "path": "${dir:state}/dumps", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "db-config", "type": "directory", "mode": "0755", - "owner": "105:106" + "owner": "105:106", + "unknown": "program" }, { "id": "storage", "type": "directory", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "functions", "type": "directory", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "settings", diff --git a/modules/systemd/README.md b/modules/systemd/README.md new file mode 100644 index 00000000..cf68a0c1 --- /dev/null +++ b/modules/systemd/README.md @@ -0,0 +1,9 @@ +# systemd + +The `systemd` module of the mesh catalogue: installs the package `systemd`; claims the seat `node-service-manager`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/systemd/module.json b/modules/systemd/module.json index 11ee4042..984ccf3a 100644 --- a/modules/systemd/module.json +++ b/modules/systemd/module.json @@ -56,7 +56,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" } ] } diff --git a/modules/telegram/README.md b/modules/telegram/README.md index f8821915..aeb1ea79 100644 --- a/modules/telegram/README.md +++ b/modules/telegram/README.md @@ -102,3 +102,9 @@ never inject one. | tool | does | |---|---| | `telegram_status` | whether it can send and why not (never the token), the bot's name, when updates last arrived, the last delivery and error, counts since start, and its rules | + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/telegram/module.json b/modules/telegram/module.json index 5534476a..95ae6f1b 100644 --- a/modules/telegram/module.json +++ b/modules/telegram/module.json @@ -54,7 +54,8 @@ "type": "directory", "mode": "0700", "owner": "telegram", - "place": "." + "place": ".", + "unknown": "program" } ], "build": { diff --git a/modules/triggerhappy/README.md b/modules/triggerhappy/README.md index a648fb12..7027cc34 100644 --- a/modules/triggerhappy/README.md +++ b/modules/triggerhappy/README.md @@ -45,3 +45,10 @@ model's module now contributes its keys. When it is pushed, the host gives back `asus-g14.conf` it kept, which still calls the predecessor's `as-user` scripts. Delete that file afterwards. The daemon reads only `mesh.conf` from then on, so the file would not fire, but `triggerhappy_check` flags any file besides the mesh's. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/etc/systemd/system/triggerhappy.service.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/triggerhappy/triggers.d`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/triggerhappy/module.json b/modules/triggerhappy/module.json index fe8507c2..18faaf4b 100644 --- a/modules/triggerhappy/module.json +++ b/modules/triggerhappy/module.json @@ -22,7 +22,8 @@ "id": "drop-ins", "type": "directory", "path": "/etc/systemd/system/triggerhappy.service.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "as-account", @@ -35,7 +36,8 @@ "id": "triggers-dir", "type": "directory", "path": "/etc/triggerhappy/triggers.d", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "triggers", diff --git a/modules/umami/README.md b/modules/umami/README.md new file mode 100644 index 00000000..f0358716 --- /dev/null +++ b/modules/umami/README.md @@ -0,0 +1,10 @@ +# umami + +The `umami` module of the mesh catalogue: runs the container image `ghcr.io/umami-software/umami`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:grants}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/umami/module.json b/modules/umami/module.json index a11f9b76..22ead419 100644 --- a/modules/umami/module.json +++ b/modules/umami/module.json @@ -67,12 +67,14 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "grants", "type": "directory", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "server-env", diff --git a/modules/unifi/README.md b/modules/unifi/README.md new file mode 100644 index 00000000..12b95230 --- /dev/null +++ b/modules/unifi/README.md @@ -0,0 +1,11 @@ +# unifi + +The `unifi` module of the mesh catalogue: runs the container image `lscr.io/linuxserver/unifi-controller`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:mesh-state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `${dir:data}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/unifi/module.json b/modules/unifi/module.json index 77510e53..2ee5cf49 100644 --- a/modules/unifi/module.json +++ b/modules/unifi/module.json @@ -104,19 +104,22 @@ "id": "mesh-state", "type": "directory", "mode": "0700", - "place": "mesh" + "place": "mesh", + "unknown": "program" }, { "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "data", "type": "directory", "mode": "0700", - "owner": "1000:1000" + "owner": "1000:1000", + "unknown": "program" }, { "id": "server", diff --git a/modules/website/README.md b/modules/website/README.md new file mode 100644 index 00000000..6819d111 --- /dev/null +++ b/modules/website/README.md @@ -0,0 +1,9 @@ +# website + +The `website` module of the mesh catalogue: runs the container image `registry-api.novox.be/novox/www`. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/website/module.json b/modules/website/module.json index 8a30f764..481cfc66 100644 --- a/modules/website/module.json +++ b/modules/website/module.json @@ -30,7 +30,8 @@ "id": "state", "type": "directory", "mode": "0700", - "place": "." + "place": ".", + "unknown": "program" }, { "id": "net", diff --git a/modules/xorg/README.md b/modules/xorg/README.md index 65265569..5172b801 100644 --- a/modules/xorg/README.md +++ b/modules/xorg/README.md @@ -202,3 +202,9 @@ bindings. Those bindings belong to that machine's hardware module, not here. - **The `# ` naming lines in the `xresources` slots** are safe only because this module merges with `-nocpp`. If the controller rendered `!` for `xresources`, that would be the format's own comment. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `~/.config/xorg`: holds only what this module declares; anything else is moved out by the node-engine to `~/.local/state/mesh-moved/xorg/` with a list, never deleted (ADR 0422 §4). diff --git a/modules/xorg/module.json b/modules/xorg/module.json index 298ad877..7b0b6b1e 100644 --- a/modules/xorg/module.json +++ b/modules/xorg/module.json @@ -89,7 +89,8 @@ "type": "directory", "path": "${machine:account-home}/.config/xorg", "owner": "${machine:account}", - "mode": "0755" + "mode": "0755", + "unknown": "move-out" }, { "id": "xresources", diff --git a/modules/zfs/README.md b/modules/zfs/README.md index 6eac079f..ecb0b5dc 100644 --- a/modules/zfs/README.md +++ b/modules/zfs/README.md @@ -222,3 +222,12 @@ The tests cover: - the health verdicts, past against new errors; - a machine without ZFS; - the manifest against the tools the bundle serves. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `/var/lib/zfs-tools`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/run/zfs-events`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/etc/zfs-tools`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). +- `/var/lib/zfs-scrub`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/zfs/module.json b/modules/zfs/module.json index 06d97f96..c109320a 100644 --- a/modules/zfs/module.json +++ b/modules/zfs/module.json @@ -142,13 +142,15 @@ "type": "directory", "path": "/var/lib/zfs-tools", "mode": "0755", - "owner": "${machine:account}" + "owner": "${machine:account}", + "unknown": "program" }, { "id": "cursor-dir", "type": "directory", "path": "/run/zfs-events", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "events", @@ -167,7 +169,8 @@ "id": "config-dir", "type": "directory", "path": "/etc/zfs-tools", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "scrub-config", @@ -180,7 +183,8 @@ "id": "scrub-state-dir", "type": "directory", "path": "/var/lib/zfs-scrub", - "mode": "0700" + "mode": "0700", + "unknown": "program" }, { "id": "scrub-run", diff --git a/modules/zsh/README.md b/modules/zsh/README.md index a2e80e0f..0104778e 100644 --- a/modules/zsh/README.md +++ b/modules/zsh/README.md @@ -22,6 +22,9 @@ The login shell as a module (novox/hq ADR 0176, ADR 0204, to-be 41). and `~/.local/bin`, `~/scripts`, `~/scripts/bin` at the start of `PATH`. The holder of `node-environment` (`node-env`) writes them; this module writes no `export` of its own. +zsh owns no folder. It writes two blocks, one into `~/.zshrc` and one into `~/.zshenv`, and every line +outside them is the person's (ADR 0422, ADR 0416). + ## The two blocks Each block is the mesh's, between `# BEGIN mesh zsh.` and `# END mesh zsh.`. Every line @@ -91,3 +94,9 @@ them by hand once the module that replaces each is assigned: - `~/.zsh/plugins/zsh-autocomplete`: loaded by nothing today. Anything else under `~/.zsh/` is yours. + +## Files it does not know + +Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416). + +- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2). diff --git a/modules/zsh/module.json b/modules/zsh/module.json index adc1234e..da125af2 100644 --- a/modules/zsh/module.json +++ b/modules/zsh/module.json @@ -125,7 +125,8 @@ "type": "directory", "place": ".", "owner": "root", - "mode": "0755" + "mode": "0755", + "unknown": "program" }, { "id": "tools-conf", diff --git a/modules/zsh/test/manifest.test.ts b/modules/zsh/test/manifest.test.ts index 25ea3f78..019e94eb 100644 --- a/modules/zsh/test/manifest.test.ts +++ b/modules/zsh/test/manifest.test.ts @@ -104,7 +104,7 @@ test("execute is a per-machine config value, served unless a machine withholds i assert.equal(m.config.execute.default, "serve"); assert.match(m.config.execute.description, /withhold/); const dir = resource("state"); - assert.deepEqual(dir, { id: "state", type: "directory", place: ".", owner: "root", mode: "0755" }); + assert.deepEqual(dir, { id: "state", type: "directory", place: ".", owner: "root", mode: "0755", unknown: "program" }); const conf = resource("tools-conf"); assert.equal(conf.type, "file"); assert.equal(conf.path, "${dir:state}/tools.conf");