Files
hq/04-ISSUES/247-a-module-cannot-put-the-operators-account-in-a-group/00-report.md
T
jschoubben 418261213c
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…
mesh/delivery superseded: a newer head of the same pull request
Remove the decision records and research efforts, which the knowledge base now holds whole (issue 426)
ADR 0290 rule 9: once the import is checked record by record, hq keeps no copy.
The records and efforts are removed; every link or path to them reads "ADR NNNN" or
"research NNN"; a design's decisions: lists "ADR NNNN". 02-DECISIONS keeps a pointer
README with the reading order's six topics, which the knowledge base reads through the
records module; 01-RESEARCH keeps a pointer README. The checks drop the rules that
judged records (the knowledge base holds each at propose; checks/README.md says where)
and refuse a record written here again. Playbooks 01 and 02 and the skills write and
read records with the knowledge base's verbs.
2026-10-11 12:56:09 +02:00

4.0 KiB

opened
opened
2026-10-05

247 — A module cannot put the operator's account in a group

What was observed

2026-10-05. The module for a peripheral-lighting daemon was assigned to the laptop. Its package installs the daemon and creates the daemon's group. The daemon then refuses to start: "User is not a member of the openrazer group". The device files are the group's, so the daemon cannot reach the devices.

The module's own check names the fix, which is to add the account to the group and log in again. No module can declare that fix:

  • The account is a user resource, and the login-shell module already declares it, to set its shell.
  • A second module that declares the same account, only to add one group, is refused as a duplicate name.
  • There is no resource for one membership on its own. A whole-account declaration that lists groups would also take from the account every group it does not list, including the operator's own.

So the step is done by hand, with sudo, outside the mesh, and nothing records why the account is in the group.

Why it matters beyond this instance

More modules need this than this one: input devices (input), serial ports (uucp), the container runtime (docker), virtual machines (libvirt, kvm), and capture or scanner hardware. Each is a fact a module knows and the operator's account needs. Today every one is a hand step that survives a reinstall only by memory. A membership added by hand is also never taken away when the module that needed it is unassigned.

Open questions

  1. Is a membership its own resource (account, group), held by the module that needs it and given back on undeclare? Or is it a contribution to the account's holder, in the way ADR 0212 lets a module contribute to a seat?
  2. A membership takes effect at the next login. How does the module say so: a finding, or a moment the power or session seat already knows?
  3. What does undeclare do with a membership the account already had before any module declared it? The host keeps what it found and gives it back, as it does with a whole file it wrote over.

How it is checked

When fixed, assigning the lighting module to a machine whose account is not in the group puts the account in the group, says that a new login is needed, and leaves the account's other groups as they were. Unassigning it removes only a membership the module added.

Re-checked 2026-10-08: still holds — the node-engine on main has no resource for one group membership, and the lighting module declares none.

Resolution — 2026-10-08

Decided in ADR 0252, built as to-be 41 WP6.

One statement above was already wrong when it was written. Since 2026-10-04 the controller has let a second module declare the account with groups only. It refuses only two modules that set the account's shell or home. Nobody used that, because this report and the lighting module's documentation both said it was refused. What was really missing:

  • the account was composed before the module's packages, so on a fresh machine its group did not exist yet;
  • nothing recorded which groups the mesh added, so nothing could be given back;
  • nothing said that a new login was the step left.

The answers to the open questions:

  1. Neither a new resource nor a contribution. It is the user resource with groups and nothing else of the account, which every node-engine already applies. A new resource kind would have been refused, whole, by every node-engine older than it.
  2. A finding, stated as health. The apply's outcome says a new login is needed. The node-engine's account judge states the module's resource of kind account unhealthy with relogin needed until the account's running service manager has the group, and the controller raises it as the module's condition.
  3. Kept. A group the account was in before any module named it is never recorded and never taken back. Only a group the mesh added is given back, and not while another declared resource asks for it.