s6-rc commands such as s6-rc, s6-rc-compile, or s6-rc-db, implement pure mechanism, and leave all the burden of policy, i.e. how to organize source files, when to compile a service database, etc., to the user. This is on purpose, but does not make it easy to integrate s6-rc in a distribution, where service files are provided by packages installed by a package manager, and where the user wants to be able to easily define which services start at boot time and which do not, etc.
The solution to this conundrum is the high-level user interface to s6-rc (and more generally to the s6 ecosystem) named s6-frontend (currently in development). But in order for s6-frontend to be a user interface and not a whole engine in its own right, some stepping stones are in order: intermediary-level helpers to manage s6-rc source definition directories in a way that maps better to the way that distributions work than just the raw s6-rc-compile.
These intermediary-level helpers made their appearance in version 0.6.0.0 of s6-rc, and they're collectively known as repo commands — simply because they manage a repository of services.
An s6-rc repository is a place in the filesystem where the repo commands perform their work and store their data. It is made of hierarchies of symlinks (lots and lots of symlinks), that ultimately point to source definition directories in the stores, as well as several compiled databases: the reference database, and the compiled databases made of the sets you have committed, including the one you will eventually install.
A repository is where offline work on services happens. It must be located on a read-write filesystem, but that filesystem does not need to be accessible during the early boot. The default repository is located in /var/lib/s6-rc/repository (configurable at build-time). Other repositories can be created and used at will, typically by non-root users who want to manage their own sets of services.
A service store is a place in the filesystem where source definition directories are written by the package manager or the user, where you can find the real contents of the services (instead of just symlinks), as in, source definition directories that are processed by s6-rc-compile. A repository will typically link to several stores: one provided by the package manager, and one — or more — provided locally by the admin. No s6-rc command will ever write to a store, but most repo commands read from all the stores.
The location of the stores is entirely determined by distribution policy, and s6-rc hardcodes no default for them. A good place to host service definition directories installed by a package manager could be, for instance, /usr/lib/s6-rc/sources. A good place to host local service definition directories managed by an administrator could be /etc/s6-rc/sources.
When a repository is created or updated, the list of all services defined in all the stores used by this repository is analyzed, and all these services are automatically compiled into a reference database, stored in the repository. The reference database is never meant to be installed or go live in any way; its purpose is mainly to give repo commands access to the full dependency graph of all the services in the store. Additionally, compiling this reference database ensures that the whole set of services defined in all the used stores is consistent: if not, the initialization fails, so the problem is reported as early as possible.
Inside a repository, a set is the fundamental unit of operation, and what users will interact the most with. A set is a map associating each service contained in the reference database (so, each service listed in all the stores used by the repository) to a given state that the user wants this service in when booting the system. This target state is also called a sub, because target states are implemented by subdirectories of the directory holding a set.
The idea is that the user can work on a set, making modifications to the target states as they see fit; the repo commands always ensure that the set will be consistent, i.e. that dependencies will be respected and target states are reachable. When satisfied with the states, the user can commit the set, then install it.
A sub is the target state for every service in a set. At all times, each service is in one and only one sub. The list of subs the service can be in is the following:
Working on a set basically means moving services from one of these subs to another, mostly choosing what services you will enable or disable, and sometimes masking services you don't want to see at all. And once you are happy with a set, you can commit it.
Committing a set means assembling a subset of all the source definition directories in the set and compiling them into a set database, replacing any previous database for the same set. This set database can then be installed.
Installing a committed set means copying the compiled set database to the place (defined by policy distribution) where it can be used as a live database, i.e. booted on, and then switching the live database to it. In other words: making the set database into the new live database.
Note that all these steps will be made easier in the near future by the higher-level user interface provided by s6-frontend.