Environments
sigil env gives you a set of programs, built from a package channel, in a shell. You describe the environment in a file, lock it, and enter it:
;; env.sgl
(environment packages: (list (pkg "core/tmux") (pkg "core/emacs")))sigil env --channel ~/src/core-channel lock -f env.sgl --lock-file env.lock
sigil env shell -f env.lock # a shell with tmux and emacs on PATH
sigil env shell -f env.lock -- emacs # or run one programThe lock records exactly which package identities and output hashes the environment contains, so the same lock gives the same programs on any machine.
While it works, sigil env reports each step on stderr: lock shows the channel check, how many packages it resolved, a [i/N] line per package (already in the store, or building, with the build time), and the total time. shell is silent once its packages have been verified; the first time, it names each package it checks. Add --quiet (-q) to any of these to turn the lines off.
sigil env apply -f env.lock -n NAME builds a profile from the same lock: ~/.sigil/env/profiles/NAME/current holds the environment's packages and their runtime dependencies (terminfo, manual pages and helper programs that come from a dependency). Where a package and a dependency both ship a file, the package's own copy is used.
Where packages live
Environment packages are kept in the environment store:
| setting | store location |
|---|---|
SIGIL_ENV_STORE set | that directory |
otherwise, SIGIL_STORE set | that directory (see the note below) |
otherwise, XDG_DATA_HOME set | $XDG_DATA_HOME/sigil/store |
| otherwise | ~/.local/share/sigil/store |
This is separate from the build cache that sigil build and sigil app install use (~/.cache/sigil/store). The cache holds build artifacts and can be deleted at any time. The environment store holds programs you run, which is why it is not under ~/.cache.
If you setSIGIL_STORE: earlier versions usedSIGIL_STOREfor everything, so it still applies to environments whenSIGIL_ENV_STOREis not set. If you pointedSIGIL_STOREat your build cache, your environment packages now live there too, and that cache's newly added items become read-only (see below). SetSIGIL_ENV_STOREto keep them apart.
Installed packages are read-only, by design
As in Nix, packages in the environment store are read-only: sigil removes write permission from every file and directory of a package as it installs it, and restores it only for its own operations (moving a damaged package to quarantine, deleting). Directories are sealed too because most accidental edits go through the directory, not the file: sed -i and many editors save by writing a new file and renaming it over the old one, and rm or mv need only the directory. Sealing just the files would stop a plain write and let all of those through.
What the seal does not do is stop a program running as you that means to change a package: you own the store, so such a program can put the write permission back. Detecting that is the job of verification (sigil env verify --full, below), not of permissions.
Because directories are read-only, a plain rm -rf of the store fails with "Permission denied". Delete through sigil instead, which lifts the seal itself:
sigil env store rm 5f13c4c6…-emacs-31.1 # one package, by name or by path
sigil env store rm --all # the whole environment storesigil env store rm only ever deletes inside the environment store: a path elsewhere, a .. escape, a symbolic link planted in the store, or --all on a directory that is not a sigil store is refused. It exits 0 when it removed something (or --all found nothing to remove), 66 when the named package does not exist, 77 when it refused, and 64 on a usage error. (sigil env remove, gc and prune are different commands: they manage profiles and generations, not the store.)
One-time setup
Packages are built with their files at a fixed location, /sigil/store/.... Every machine builds and verifies the same bytes, which is what makes a package built on one machine usable on another. For those paths to work on your machine, /sigil has to point at the directory holding your environment store. That is one symbolic link, created once:
sigil env setupIt shows the exact command it would run (for example sudo ln -sT /home/you/.local/share/sigil /sigil) and asks before running it. It creates your store directory if needed; nothing outside your home directory changes unless you answer y.
Why it needs root once: / belongs to root, so creating /sigil does too. After that, sigil never needs root again: the store itself is yours.
Run it as yourself, not with sudo. It asks for sudo itself, only for the ln. Run as root, it would link /sigil to root's store, which you cannot read, so it refuses (exit 64). A store that really belongs to root has to be named explicitly: sigil env --store PATH setup.
What happens if you decline: anything whose data paths can be set through environment variables still works inside sigil env shell. Programs that have /sigil/store paths built into them, Emacs for example, cannot find their own files, inside the shell or outside it. sigil env shell prints a one-line reminder the first time. Run sigil env setup whenever you are ready.
How to undo it: remove the link, sudo rm /sigil. Your store and your locks are untouched.
Exit codes, for scripts and installers:
| code | meaning |
|---|---|
| 0 | the link was created |
| 2 | the link was already set up; nothing was done |
| 3 | declined: you said no, the run was not interactive, or there is no sudo/doas (the command was printed) |
| 4 | refused: /sigil exists and is not your link (another user's store, a stale or indirect link, a real directory); it was not touched |
| 5 | you said yes, but the link command did not produce the expected link |
| 64 | usage error, including running it as root (see below) |
Any other non-zero code (such as 1) means sigil env setup itself failed unexpectedly.
The trust model
This is the same model as a single-user Nix installation. The environment store belongs to you, so any program running as you can change files in it.
What sigil env shell -f env.lock does on every start is check each package in the lock against its recorded hash, and refuse anything that no longer matches, moving it to quarantine. To keep that fast, it remembers which packages it has already checked, together with each file's size, permissions and times; a package whose files have not changed since is not re-read. This catches accidental changes, and it catches a careless tamper: even putting a file's size and modification time back does not hide it, because the file's change time moves too.
It does not protect you from a program that is already running as you and sets out to deceive sigil: the record of what was checked lives in the same store, so such a program can rewrite it along with the files. Treat the environment store like the rest of your home directory. To check an environment without trusting that record, re-reading every package against the lock:
sigil env verify --full -f env.lockWithout --full, sigil env verify -f env.lock runs the same check as sigil env shell. Both exit 71 if a package fails verification.
Two things are not checked at all: programs started outside sigil through /sigil paths (a desktop launcher, a script), and sigil env shell -n PROFILE, which enters a profile created by sigil env apply without re-reading its lock. Run sigil env verify when that matters.
macOS
sigil env currently builds for Linux only. On macOS, / is read-only, and a future version of sigil env setup would add /sigil through /etc/synthetic.conf, the mechanism Nix uses for /nix.