Skip to content

feat(hjem): add the hjem integration - #94

Merged
clhodapp merged 2 commits into
mainfrom
feat/hjem
Oct 17, 2026
Merged

clhodapp merged 2 commits into
mainfrom
feat/hjem

Conversation

@clhodapp

@clhodapp clhodapp commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Adds caisson.hjem, an integration over hjem whose configurations are the files and packages of one user.

What an hjem configuration is

hjem evaluates a user only inside its NixOS and nix-darwin modules, as an entry of hjem.users. caisson evaluates hjem's user module, modules/common/user.nix, with its own evalModules. It passes the arguments hjem's OS modules pass: hjem's library as hjem-lib, the user's name as name, the package set as pkgs, and the machine above the configuration as osConfig. user defaults to the name the configuration is declared under. The configuration is found by that name in configs/hjem.

The outputs are what hjem's tools read:

Output Value
manifest the version 3 manifest of the user's files, as hjem's OS modules write it
manifestFile that manifest as a JSON file, checked against hjem's schema with cue vet when built
packages the user's packages
cli hjem's CLI, built from the hjem source the configuration is evaluated with

A top publishes the configuration as hjemConfigurations.<name> with manifest and packages. That is the attribute hjem standalone switch --flake . reads for $USER. The value of an hjem configuration that is a top has manifest and packages as well, which hjem standalone switch --config reads from a file. The manifest of the evaluation sits under caisson.manifest behind an outPath, so the CLI serializes it as a string.

Inside a NixOS machine

caisson does not use hjem's NixOS module. The new NixOS module hjem-activation, imported by caisson's default NixOS module, writes the units hjem's NixOS module writes, under the same names. These are hjem-prepare, the templates hjem-activate@, hjem-reload@ and hjem-update-state@, hjem-cleanup and the target hjem. The unit scripts are the same, with strict shell checks, and they read the manifests of the generation from one directory. Each instance runs the CLI of the configuration of its user. The module also adds each user's packages to users.users.<user>.packages and the user's extraDependencies to the system closure, as upstream does.

Through caisson.forChildren, caisson's default NixOS module gives each hjem configuration the hjem module nixos-parent. That module sets directory from the machine's account for the user, and refuses a user without an enabled account. An hjem configuration inside a NixOS machine also imports hjem's modules/nixos/systemd.nix with the machine's utils and options. As a result, it can declare systemd user units, like a user embedded by hjem's NixOS module.

The units link with hjem's own CLI and the backup prefix .backup-. hjem's NixOS options for another linker or for systemd-tmpfiles have no counterpart.

The cost of one more integration

Every evaluation declares a caisson.<integration>.configurations option for every integration, and childrenOf read all of them. The first commit makes childrenOf read only the options that a module defines, and builds the option types once. With hjem added, caisson's evaluation overhead in the eval-weight check drops from 4.26 MB to 4.15 MB, and the ceiling stays 4.28 MB.

Tests

  • The pinned-world suite pins hjem in tests/dependencies and checks two cases.
    • A standalone top gives the manifest, packages and placeholder the CLI reads.
    • An hjem configuration inside a NixOS machine takes its directory from the account. Its manifest, which includes a systemd user unit, equals the manifest hjem's NixOS module makes from the same user module. The machine has the template units and requires the instance for the user, and the top publishes hjemConfigurations.probe.
  • The new hjem-system check builds the manifest file, which runs cue vet against hjem's schema, and the six units, which runs shellcheck on their scripts.
  • The unit tests and the argument-errors check cover the new entry points.

Activation on a running machine is not tested.

All 18 workspace consumers pass nix flake check --no-build at #96, which contains this branch. That run puts the branch in place of both caisson pins of each consumer: the root input, and the tests/dependencies lock that the checks partition reads. An earlier run on this branch alone overrode only the root input, so those partitions then ran against the caisson they pin.

🤖 Generated with Claude Code

clhodapp and others added 2 commits October 17, 2026 00:34
…ines

Every evaluation declares `caisson.<integration>.configurations` for
every integration caisson ships, and `childrenOf` read each of them,
merging an option that only holds its default. It now reads an option
only when a module defines it, and the types of the options are built
once for all integrations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An hjem configuration is the files and packages of a user, evaluated
with hjem's user module at every system in force where it is declared.
Its outputs are the version 3 manifest hjem's OS modules write, that
manifest as a file checked with hjem's schema, the packages and hjem's
CLI. It is published as `hjemConfigurations.<name>`, which
`hjem standalone switch --flake` reads, and a top projects to what
`hjem standalone switch --config` reads.

A NixOS configuration activates the hjem configurations declared inside
it with the NixOS module `hjem-activation`. It writes the template
units hjem's NixOS module writes, under the same names, and each
instance runs the CLI of the configuration of its user. caisson's
default NixOS module imports it, and gives each hjem configuration the
hjem module `nixos-parent`, which takes the home directory from the
machine's account for the user. An hjem configuration inside a NixOS
machine also imports hjem's `modules/nixos/systemd.nix` with the
`utils` and options of the machine, so it declares systemd user units
as a user hjem's NixOS module embeds does.

The `hjem-system` check builds the units and the manifest file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant