Fixes novox/hq issue 437 (node-mounts.list says a share is mounted when only its automount is armed).
What was wrong
say() in cmd/mounts/mounts.go took the "mounted" branch whenever MountedNow was set. ParseMountinfo keeps the last line per mount point, and an armed automount with nothing mounted under it leaves only its autofs systemd-1 line there. The look (apply.gojudge) and the checks before a mount (data.go) already excluded autofs; List did not.
Captured on the desktop (shanks) on 2026-10-11 at 02:16 local, read-only, with main at 372b6c2 (the fix for issue 374) already running there (no systemctl "invalid option" note, unit states present):
node-mounts.listmounted_now for /mnt/recalbox: type autofs, source systemd-1.
node-mounts.list said: /mnt/recalbox (cifs from //…/Share): mounted; from /etc/fstab line 23, no nofail, while its own share state said absent (the host does not answer).
/storage/media (automount running, nfs4 over autofs) said mounted, which is right.
What changes
One judgement, Mounted.IsAutomount() (type is autofs), now used by say(), judge in apply.go and both checks in data.go, so the three cannot disagree again.
say() takes the "mounted" branch only when the line at the point is not the automount's own. The armed case then falls to the existing "not mounted, waits for its first use (automount waiting)" line.
mounted_now in the JSON still carries the autofs line as mountinfo shows it; only the said line's judgement changes.
What I checked
New test TestListSaysAnArmedAutomountIsNotMounted, built from the desktop's recalbox shapes (unit properties, autofs superblock options and fstab line as the live list showed them, addresses replaced with 192.0.2.x). It failed on unfixed main with exactly the live wrong line (…: mounted; from /etc/fstab line 1, no nofail) and passes now.
TestList still says /mnt/backup (nfs4 line over its autofs line) is mounted.
go vet ./..., go test ./... -count=1 in modules/mounts, and checks/words all pass.
What I did not verify
The mountinfo line's leading ids (40 22 0:50 …) are copied from the module's existing fixture, not read from the desktop; list does not return them. Only the fields after - matter to the parser.
Not built or delivered; the live answer after the fix is not seen yet. After delivery, shanks/node-mounts.list should say /mnt/recalbox …: not mounted, waits for its first use (automount waiting); … while nothing is mounted there.
Fixes novox/hq issue 437 (node-mounts.list says a share is mounted when only its automount is armed).
## What was wrong
`say()` in `cmd/mounts/mounts.go` took the "mounted" branch whenever `MountedNow` was set. `ParseMountinfo` keeps the last line per mount point, and an armed automount with nothing mounted under it leaves only its `autofs systemd-1` line there. The look (`apply.go` `judge`) and the checks before a mount (`data.go`) already excluded autofs; `List` did not.
Captured on the desktop (shanks) on 2026-10-11 at 02:16 local, read-only, with main at 372b6c2 (the fix for issue 374) already running there (no systemctl "invalid option" note, unit states present):
- `node-service-manager.status`: `mnt-recalbox.mount` inactive/dead; `mnt-recalbox.automount` active/waiting.
- `node-mounts.list` `mounted_now` for /mnt/recalbox: type `autofs`, source `systemd-1`.
- `node-mounts.list` said: `/mnt/recalbox (cifs from //…/Share): mounted; from /etc/fstab line 23, no nofail`, while its own share state said `absent` (the host does not answer).
- /storage/media (automount running, nfs4 over autofs) said mounted, which is right.
## What changes
- One judgement, `Mounted.IsAutomount()` (type is autofs), now used by `say()`, `judge` in apply.go and both checks in data.go, so the three cannot disagree again.
- `say()` takes the "mounted" branch only when the line at the point is not the automount's own. The armed case then falls to the existing "not mounted, waits for its first use (automount waiting)" line.
- `mounted_now` in the JSON still carries the autofs line as mountinfo shows it; only the said line's judgement changes.
## What I checked
- New test `TestListSaysAnArmedAutomountIsNotMounted`, built from the desktop's recalbox shapes (unit properties, autofs superblock options and fstab line as the live list showed them, addresses replaced with 192.0.2.x). It failed on unfixed main with exactly the live wrong line (`…: mounted; from /etc/fstab line 1, no nofail`) and passes now.
- `TestList` still says /mnt/backup (nfs4 line over its autofs line) is mounted.
- `go vet ./...`, `go test ./... -count=1` in modules/mounts, and `checks/words` all pass.
## What I did not verify
- The mountinfo line's leading ids (`40 22 0:50 …`) are copied from the module's existing fixture, not read from the desktop; `list` does not return them. Only the fields after ` - ` matter to the parser.
- Not built or delivered; the live answer after the fix is not seen yet. After delivery, `shanks/node-mounts.list` should say `/mnt/recalbox …: not mounted, waits for its first use (automount waiting); …` while nothing is mounted there.
The autofs line an armed automount leaves in mountinfo made List say
"mounted" while nothing was mounted. One judgement, Mounted.IsAutomount,
now serves List, the look and the checks before a mount.
Deliverynovox/mesh-catalog@520763e98dc3 — delivered since 2026-10-11T00:31:01Z
Delivery plan — builds mounts → shanks; no bus step
tier 0: mounts
shanks: receives mounts
Machines
mounts on shanks: passed — healthy 3 times over 2m28s
mounts on the rest running it: sent
Transitions
2026-10-11 00:18 (new) → proposed (announced): novox/mesh-catalog#196's head announced
2026-10-11 00:19 proposed → checked (checked): the verdict names this commit
2026-10-11 00:19 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-11 00:27 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-11 00:27 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path — not a failed walk that carried a later commit for it, after which it waits for a walk of its own commit
2026-10-11 00:31 delivering → delivered (done): its walk is done, carrying its own commit: every machine of its deploy plan passed, or was left as its policy says
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-catalog@520763e98dc3` — **delivered** since 2026-10-11T00:31:01Z
**Delivery plan** — builds mounts → shanks; no bus step
- tier 0: mounts
- shanks: receives mounts
**Machines**
- mounts on shanks: passed — healthy 3 times over 2m28s
- mounts on the rest running it: sent
**Transitions**
- 2026-10-11 00:18 (new) → proposed (announced): novox/mesh-catalog#196's head announced
- 2026-10-11 00:19 proposed → checked (checked): the verdict names this commit
- 2026-10-11 00:19 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-11 00:27 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-11 00:27 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path — not a failed walk that carried a later commit for it, after which it waits for a walk of its own commit
- 2026-10-11 00:31 delivering → delivered (done): its walk is done, carrying its own commit: every machine of its deploy plan passed, or was left as its policy says
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: mounts)
mesh/repo-check: PASS — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
Delivery plan — builds mounts → shanks; no bus step
tier 0: mounts
shanks: receives mounts
read by no module's build: modules/mounts/cmd/mounts/mounts_test.go
Run by the build seat on ace as build-1791677895920345677 (builds --log build-1791677895920345677).
--- the gate: mounts
mounts: ok, 3 tool(s), invokes seat:mesh-controller.data, keeps state shares, reads nfs-server.exports, ready: apply by unit every 30s; watch by its tool mounts_health every 1m0s; WARNING: config ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339)
long-running resources without health: 0
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-11T00:14:44Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-11T00:14:44Z
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 1 module(s) in 1 tier(s): mounts
notes:
- modules/mounts/cmd/mounts/mounts_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok git.novox.be/novox/mesh-catalog/checks/words 0.002s
words: 12 retired words and 70 daemons' lines, none in the 39398 strings of 654 files
ok git.novox.be/novox/mesh-catalog/checks/agenthome 0.011s
agent-home: no archive and no file written into under the agent's home
ok git.novox.be/novox/mesh-catalog/checks/paths 0.005s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 69, as kept
testing modules/mounts
ok mounts/cmd/mounts 1.152s
--- its merge-check-typescript.sh (typescript toolchain)
**Merge check** at `520763e9`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: mounts)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
**Delivery plan** — builds mounts → shanks; no bus step
- tier 0: mounts
- shanks: receives mounts
- read by no module's build: modules/mounts/cmd/mounts/mounts_test.go
Run by the build seat on ace as `build-1791677895920345677` (`builds --log build-1791677895920345677`).
```
--- the gate: mounts
mounts: ok, 3 tool(s), invokes seat:mesh-controller.data, keeps state shares, reads nfs-server.exports, ready: apply by unit every 30s; watch by its tool mounts_health every 1m0s; WARNING: config ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339)
long-running resources without health: 0
files asking for a setting without saying whether it is trusted: 1
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-11T00:14:44Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-11T00:14:44Z
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 1 module(s) in 1 tier(s): mounts
notes:
- modules/mounts/cmd/mounts/mounts_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok git.novox.be/novox/mesh-catalog/checks/words 0.002s
words: 12 retired words and 70 daemons' lines, none in the 39398 strings of 654 files
ok git.novox.be/novox/mesh-catalog/checks/agenthome 0.011s
agent-home: no archive and no file written into under the agent's home
ok git.novox.be/novox/mesh-catalog/checks/paths 0.005s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 69, as kept
testing modules/mounts
ok mounts/cmd/mounts 1.152s
--- its merge-check-typescript.sh (typescript toolchain)
```
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes novox/hq issue 437 (node-mounts.list says a share is mounted when only its automount is armed).
What was wrong
say()incmd/mounts/mounts.gotook the "mounted" branch wheneverMountedNowwas set.ParseMountinfokeeps the last line per mount point, and an armed automount with nothing mounted under it leaves only itsautofs systemd-1line there. The look (apply.gojudge) and the checks before a mount (data.go) already excluded autofs;Listdid not.Captured on the desktop (shanks) on 2026-10-11 at 02:16 local, read-only, with main at
372b6c2(the fix for issue 374) already running there (no systemctl "invalid option" note, unit states present):node-service-manager.status:mnt-recalbox.mountinactive/dead;mnt-recalbox.automountactive/waiting.node-mounts.listmounted_nowfor /mnt/recalbox: typeautofs, sourcesystemd-1.node-mounts.listsaid:/mnt/recalbox (cifs from //…/Share): mounted; from /etc/fstab line 23, no nofail, while its own share state saidabsent(the host does not answer).What changes
Mounted.IsAutomount()(type is autofs), now used bysay(),judgein apply.go and both checks in data.go, so the three cannot disagree again.say()takes the "mounted" branch only when the line at the point is not the automount's own. The armed case then falls to the existing "not mounted, waits for its first use (automount waiting)" line.mounted_nowin the JSON still carries the autofs line as mountinfo shows it; only the said line's judgement changes.What I checked
TestListSaysAnArmedAutomountIsNotMounted, built from the desktop's recalbox shapes (unit properties, autofs superblock options and fstab line as the live list showed them, addresses replaced with 192.0.2.x). It failed on unfixed main with exactly the live wrong line (…: mounted; from /etc/fstab line 1, no nofail) and passes now.TestListstill says /mnt/backup (nfs4 line over its autofs line) is mounted.go vet ./...,go test ./... -count=1in modules/mounts, andchecks/wordsall pass.What I did not verify
40 22 0:50 …) are copied from the module's existing fixture, not read from the desktop;listdoes not return them. Only the fields after-matter to the parser.shanks/node-mounts.listshould say/mnt/recalbox …: not mounted, waits for its first use (automount waiting); …while nothing is mounted there.Delivery
novox/mesh-catalog@520763e98dc3— delivered since 2026-10-11T00:31:01ZDelivery plan — builds mounts → shanks; no bus step
Machines
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
520763e9mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: mounts)mesh/repo-check: PASS — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)Delivery plan — builds mounts → shanks; no bus step
Run by the build seat on ace as
build-1791677895920345677(builds --log build-1791677895920345677).