Thanks. I thought through the model you proposed.
Let me answer your questions directly first, because they made me
reconsider how the PR itself should work.
> Is it reasonable to expect a distro to install a fully functional,
> fully expanded (i.e. no need to interpret XDG variables) configuration
> file at user creation time, and to automatically set an environment
> variable in the user's login shell to that configuration file? If it's
> not, it means that /etc/s6-user.conf, as you have named it, needs a
> layer of interpretation so that the XDG variables expand to the correct
> value. It is doable; it just means a little more effort.
I think the second option is the right one: `/etc/s6-user.conf`
should be shared by all users and needs a layer of XDG interpretation.
The main reason is that package-managed service sources are distribution
policy, not user policy.
For example, suppose the distro generates a configuration for every user
containing:
```
storelist = /usr/share/s6/user/sources:/etc/s6/user/sources
```
and later moves its package-managed sources to:
```
/usr/lib/s6/user/sources
```
It now has to find and rewrite every generated user configuration. The
path was copied into user-owned state even though the user was never the
owner of that policy.
I think the distro/admin should retain ownership of shared source paths.
A user should only become responsible for such configuration if they
explicitly choose to override it themselves.
A smaller benefit is that this also avoids putting distro-specific paths
into user homes, making those homes somewhat more portable.
So I agree that s6-frontend should interpret XDG-dependent values in one
system-provided user configuration rather than requiring a fully expanded
configuration to be generated for every account.
> If the configuration file remains the unique entry point, I can
> probably remove the --user flag entirely by checking a user=1
> variable that user configuration files would set. That would allow
> XDG processing in s6-frontend itself rather than duplicating it in
> the layer that reads the config file.
I disagree with removing --user flag. I think instance selection
should stay explicit:
```
s6 ...
-> system instance
s6 --user ...
-> invoking user's user instance
```
I don't think the login environment should silently change what plain
`s6` means.
Consider a normal user with a correctly initialized login environment:
```
$ s6 --user status
-> user instance
```
If `XDG_RUNTIME_DIR` is unexpectedly missing:
```
$ s6 --user status
-> error: user runtime environment is incomplete
```
That is a useful failure.
With configuration selected implicitly through the login environment,
the same failure can instead become:
```
$ s6 status
-> user profile selector was lost
-> silently loads system configuration
-> tries /run/service, /var/lib/s6-rc/repository, ...
-> permission denied
```
The error now describes the wrong problem, and the command targeted an
instance the user never intended to access.
Root makes the implicit model more confusing.
If root is actually logged in and has a personal user manager running,
the login environment would naturally select root's user profile:
```
root# s6 status
-> root's user instance
```
But root also needs to administer the system instance. That would require
either:
```
root# s6 --system status
```
or obtaining an environment where the user-profile selector is absent,
for example via:
```
root# sudo s6 status
```
Neither is particularly obvious.
With explicit selection there is only one special selector:
```
root# s6 status
-> system
root# s6 --user status
-> root's user instance
```
For a normal user:
```
$ sudo s6 status
-> system
```
also follows naturally from the same rule.
So I think one explicit `--user` flag is simpler than making plain `s6`
context-dependent and then needing a second `--system` mechanism to
escape that context.
For the same reason, I do not think `user=1` is necessary. `--user`
already says:
```
select the user namespace
use the user profile
perform user/XDG resolution
```
A `user=1` variable would encode the same state a second time and require
defining what happens when the command-line selection and configuration
disagree.
So the rule I prefer is:
```
command line selects the namespace;
configuration defines the layout inside that namespace.
```
> More generally, what needs to be the default set by the system,
> and what needs to be overridable by the user and to what extent?
This question made me reconsider how my current PR divides user
configuration between compile time and runtime.
The current PR deliberately avoids making `/etc/s6-user.conf`
XDG-aware. Because of that, I added compiled defaults such as:
```
--user-conffile=/etc/s6-user.conf
--with-user-store-list=/usr/share/s6/user/sources:/etc/s6/user/sources
--with-user-source-subdir=/s6/sources
--with-user-repo-subdir=/s6-rc/repository
--with-user-bootdb-subdir=/s6-rc/compiled/current
```
The user-mode resolver then combines those values with the user's XDG
directories.
Conceptually, the current defaults resolve to:
```
scandir
$XDG_RUNTIME_DIR/service
livedir
$XDG_RUNTIME_DIR/s6-rc
stmpdir
$XDG_RUNTIME_DIR/s6-frontend
repodir
$XDG_STATE_HOME/s6-rc/repository
bootdb
$XDG_STATE_HOME/s6-rc/compiled/current
storelist
/usr/share/s6/user/sources:
/etc/s6/user/sources:
$XDG_CONFIG_HOME/s6/sources
```
I think having compiled defaults is fine. The existing system side
already has compiled defaults, and distributions may reasonably want to
change those at build time.
The mistake in my PR is relying on those compiled values to express
normal distro user-service policy.
For example, `--with-user-repo-subdir` only lets the distro configure
the suffix. The resolver itself hardcodes the fact that the repository
must be below `XDG_STATE_HOME`.
Likewise, the configured user `storelist` currently only describes the
shared part of the list; the personal source store below
`XDG_CONFIG_HOME` is appended separately by the resolver.
That means `/etc/s6-user.conf` cannot describe the complete effective
user layout.
I originally did this because I did not want user configuration files
to require interpretation. I now think that was the wrong tradeoff.
The config should be interpretable, and the compiled values should just
remain defaults.
The model I now have in mind is:
```
compile time:
compiled default user paths remain available
--user-conffile=/etc/s6-user.conf
and the existing/new --with-user-* options may change
the compiled fallback defaults
runtime:
s6 --user loads /etc/s6-user.conf
values present there override the corresponding compiled
user defaults
s6-frontend then resolves the supported XDG references
against the invoking user's environment
```
The user configuration should be able to specify complete values, not
only suffixes or portions of them.
For example, a distro could install:
```
/etc/s6-user.conf
```
containing:
```
scandir = ${XDG_RUNTIME_DIR}/service
livedir = ${XDG_RUNTIME_DIR}/s6-rc
stmpdir = ${XDG_RUNTIME_DIR}/s6-frontend
repodir = ${XDG_STATE_HOME}/s6/repo
bootdb = ${XDG_STATE_HOME}/s6/rc/compiled
storelist = /etc/s6/user/sv:/etc/s6/user/adminsv:${XDG_CONFIG_HOME}/s6/sv
```
Here `storelist` is the complete store list. s6-frontend does not append
another hardcoded personal store afterwards.
Likewise, `repodir` is the complete repository policy. It happens to use
`XDG_STATE_HOME` in this example, but the distro is no longer restricted
to a compiled suffix below a hardcoded XDG base.
If `/etc/s6-user.conf` does not override one of these values, the
compiled default is used instead.
For user configuration I would only interpret a small explicit set of
references:
```
${HOME}
${XDG_CONFIG_HOME}
${XDG_STATE_HOME}
${XDG_RUNTIME_DIR}
```
with the normal XDG fallbacks where applicable, and
`XDG_RUNTIME_DIR` required for live user operations.
Together with the earlier points, the direction would therefore be:
- keep `--user`;
- keep separate system and user configuration files;
- make plain `s6` always target the system instance;
- make `s6 --user` always target the invoking user's instance;
- not introduce `user=1`;
- not require generated per-account configurations;
- keep compiled user defaults;
- make `/etc/s6-user.conf` capable of overriding the complete user
layout;
- make user configuration XDG-aware.
There is one separate future issue that follows from the ownership
question above.
A user may eventually want to create their own user-profile override
under `XDG_CONFIG_HOME`.
I think that is reasonable, and it is importantly different from a
distro generating that file for them.
If the distro generates a user configuration containing distro-owned
paths, the distro still owns that policy and is responsible for updating
it when its packaging layout changes.
If the user explicitly creates their own override and changes those
paths, they have deliberately taken ownership of that configuration. If
it later becomes stale because the distro changes something they chose
to override, that is now their configuration to maintain.
Supporting that properly would add another configuration layer to the
resolver. It also affects launcher-sensitive settings such as `scandir`:
a launcher for the user's supervision tree would need to provide an
equivalent override mechanism, and the distro would be responsible for
configuring both sides consistently.
I think both components should eventually provide that possibility
without depending on each other, leaving it to distro policy to enable
and integrate it.
But I would leave that for a later change.
I think that for the current goal, one shared user profile is
sufficient. Users still
have independent personal sources, repositories, compiled databases,
enabled sets and runtime state; they simply cannot yet override the
layout of those objects themselves.
On Sat, Sep 5, 2026 at 9:06 AM Laurent Bercot
<[email protected]> wrote:
>
>
> I finally could take the time to read everything with attention. Thank
> you for this detailed explanation!
>
> I agree with more or less all your points. Here is where I'm coming
> from:
>
> - "User services" are not yet a thing in the s6 ecosystem: the precise
> definition of what they do, and a fortiori how they're implemented, is
> very distro-dependent and it's difficult to program mechanisms that are
> usable for any distro without hardcoding policy. Consequently, it is
> expected that distributions would helm the efforts to add user services
> to s6, and your proposition is exactly the kind of thing I expected (and
> was hoping for).
>
> - The existing mechanisms are very much placeholders and subject to
> heavy modifications as long as we can design something good and
> cohesive.
>
> - You are right in identifying s6-frontend, the s6 command, as the
> place to handle distribution packaging of user services.
>
> - In my view, ideally, users would have their own s6.conf
> configuration file that defines all the relevant variables for its user;
> the location file would typically be in the user environment, set at
> login time. This way, users could just use "s6" instead of "s6 -u",
> which
> I think is a better UI. A few people convinced me that having a --user
> flag was a good thing, e.g. for testing, or if root has its personal
> user services; that's why I added the flag. Ultimately though, I think
> having "s6" automatically pick up the relevant user configuration file
> by default makes for a better experience, and I would like it to be the
> normal case, if at all possible.
>
> - I am totally open to rewriting the --user option, in particular
> override priority, if necessary. Things are absolutely not set in stone
> here.
>
> - I myself do not use user services (or any login manager of any kind)
> so I would very much like participation from people who do.
>
> So my first questions would be:
>
> - Is it reasonable to expect a distro to install a fully functional,
> fully expanded (i.e. no need to interpret XDG variables) configuration
> file at user creation time, and to automatically set an environment
> variable in the user's login shell to that configuration file? If it's
> not, it means that /etc/s6-user.conf, as you have named it, needs a
> layer of interpretation so that the XDG variables expand to the correct
> value. It is doable; it just means a little more effort.
> - More generally, what needs to be the default set by the system,
> and what needs to be overridable by the user and to what extent?
> - If the configuration file remains the unique entry point, I can
> probably remove the --user flag entirely by checking a user=1 variable
> that user configuration files would set. That would allow XDG processing
> in s6-frontend itself rather than duplicating it in the layer that reads
> the config file.
>
> What do you (plural) think?
>
> --
> Laurent
>