Skip to content

Take the files of a registry entry from the modules that name them and follow shared keys - #155

Merged
clhodapp merged 5 commits into
mainfrom
fix/registries-entry-files
Nov 13, 2026
Merged

clhodapp merged 5 commits into
mainfrom
fix/registries-entry-files

Conversation

@clhodapp

@clhodapp clhodapp commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

The check registries decides which caisson.* definitions belong to a registry entry by comparing the files of the definitions with the files of the entry. It got the files of an entry wrong in two cases, and reported definitions the entry does not make or declarations it does import.

A configuration module that imports an entry

The module system gives a module that names no file the file of the module that imports it. The registry wraps each entry in such modules. The entry of a listed project also passes through the module that lib.types.deferredModule merges from the definitions of caisson.exports.modules, which names no file and imports several modules. When a configuration module imports the entry, that merged module carries the file of the configuration module, and the check counted the definitions of the configuration module as definitions of the entry.

The flake-parts configuration of the test flake nixpkgs-overlay-export defines caisson.pkgOverlays.exported and imports caisson/nixpkgs, and its check registries failed with:

`modules.flake.caisson/nixpkgs` of the project `caisson`, file tests/integration/nixpkgs-overlay-export/configs/flake/nixpkgs-overlay-export, evaluated in the caisson top:
  defines `caisson.pkgOverlays.exported` in tests/integration/nixpkgs-overlay-export/configs/flake/nixpkgs-overlay-export, declared in modules/generic/core/caisson/pkgOverlays.nix

A module names its file when its file differs from the file of the module that imports it. The files of an entry are now the files that the modules below the entry name, and a definition belongs to the entry only when one of those files makes it. The file shown for an entry is the first of those files whose module does more than wrap a single module that names its file, so an entry of a listed project shows the file of its module.

A copy of the core module under the same key

The module system evaluates the modules that share a key once, at the first place it reaches one of them. ch-personal-machines pins a revision of caisson and lists ch-facter, which pins another revision. ch-facter/default imports caisson/core from the copy of caisson that ch-facter pins, and the NixOS configuration evaluates the core module from the copy that ch-personal-machines pins. The declaration of caisson.forNearestChildren.extraDefaultModuleImports is therefore in a file of that copy, and the check reported that ch-facter/default imports no declaration of the option. The files of an entry are now the files named by the modules of every key the entry reaches, over every place the import graph holds a module of that key.

Tests

The pinned-world suite has fixtures for each case under tests/pinned-world/registries/modules/nixos:

  • importer imports caisson/activation-marker of the generic class and defines caisson.importerNote, which a file beside it declares. registriesIgnoresTheDefinitionsOfTheModuleThatImportsAnEntry reads that the check passes, and that the definition is recorded for importer and not for caisson/activation-marker. It fails on main.
  • copied-core imports a module at another file under the key of the core module of caisson for the nixos class, and defines caisson.structural.exportNote. registriesFollowsTheKeyOfAModuleToItsDeclarations reads that the check passes and records the definition as declared. It fails with the first fix alone.

registriesRefusesAnEntryWithoutItsDeclaration passes on this branch: the check fails for the module undeclared, and its message names the entry, its file, the option and the file that declares the option.

The checks of the test flakes

The checks configuration publishes the check registries of each test flake as <test flake>-registries, because the caisson top of caisson publishes the check registries of caisson under that name: basic-composition-registries, minimal-consumer-registries, module-class-export-registries, lib-consumer-chain-registries, nixpkgs-consumer-registries, nixpkgs-overlay-export-registries, nixpkgs-no-pkg-sets-registries, nixpkgs-pkg-sets-registries, nixpkgs-lib-only-registries, pkg-overlays-registry-producer-registries, pkg-overlays-registry-consumer-registries and unit-registries. checks-evaluation-registries comes from checks-evaluation.top, as before.

Measurements

The check registries of ch-personal-machines and ch-emacs-config, read from caisson.manifest.outputs.checks.x86_64-linux.registries with --override-input caisson set to this branch:

  • ch-personal-machines: on main the check reports ch-facter/default, modules.flake.default and modules.nixos.default. On this branch it reports modules.flake.default and modules.nixos.default. Each defines options under caisson in files of ch-personal-machines (modules/flake/default/ch-personal-machines/…, modules/nixos/default/ch-personal-machines) and imports no module that declares them.
  • ch-emacs-config: passes on main and on this branch.

🤖 Generated with Claude Code

@clhodapp clhodapp self-assigned this Nov 12, 2026
@clhodapp
clhodapp force-pushed the fix/registries-entry-files branch from dc122f3 to adb1d71 Compare November 12, 2026 08:44
clhodapp and others added 5 commits November 12, 2026 00:55
… name them

The module system gives a module that names no file the file of the
module that imports it. The registry wraps an entry in such modules,
and the entry of a listed project also passes through the module that
`lib.types.deferredModule` merges from the definitions of
`caisson.exports.modules`, which names no file and imports several
modules. When a configuration module imports such an entry, that
merged module carries the file of the configuration module, so the
check `registries` counted the definitions of the configuration module
as definitions of the entry. The flake-parts configuration of the test
flake `nixpkgs-overlay-export` defines `caisson.pkgOverlays.exported`
and imports `caisson/nixpkgs`, and the check reported the definition
for `caisson/nixpkgs`.

A module names its file when its file differs from the file of the
module that imports it. The files of an entry are now the files that
the modules below the entry name, and a definition belongs to the
entry only when one of those files makes it. The file shown for an
entry is the first of those files whose module does more than wrap a
single module that names its file, so an entry of a listed project
shows its module rather than the file of the definition of
`caisson.exports.modules`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and defines an option

The module `importer` of tests/pinned-world/registries imports the
entry `caisson/activation-marker` of the project caisson and defines
`caisson.importerNote`, which a file beside it declares. The check
`registriesIgnoresTheDefinitionsOfTheModuleThatImportsAnEntry` reads
that the check `registries` passes, that the definition is recorded
for `importer`, and that it is not recorded for
`caisson/activation-marker`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The module system evaluates the modules that share a key once, at the
first place it reaches one of them, and the import graph holds each of
them where it is imported. ch-personal-machines pins a revision of
caisson and lists ch-facter, which pins another revision. The entry
`ch-facter/default` of the class caisson-facter imports
`caisson/core` from the copy of caisson that ch-facter pins, and the
NixOS configuration evaluates the core module from the copy that
ch-personal-machines pins, so the declaration of
`caisson.forNearestChildren.extraDefaultModuleImports` is in a file of
that copy. The check `registries` compared files and reported that
`ch-facter/default` imports no declaration of the option.

The files of an entry are now the files named by the modules of every
key the entry reaches, over every place the graph holds a module of
that key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r its key

The module `copied-core` of tests/pinned-world/registries imports a
module at another file under the key of the core module of caisson for
the nixos class, and defines `caisson.structural.exportNote`. The check
`registriesFollowsTheKeyOfAModuleToItsDeclarations` reads that the
check `registries` passes and records the definition as declared.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts name

Each test flake that is a caisson top has the check `registries`, and
the caisson top of caisson publishes the check `registries` of caisson
under that name. The checks configuration publishes the check of a
test flake as `<test flake>-registries`, such as
`nixpkgs-overlay-export-registries`, so `nix flake check` builds it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@clhodapp
clhodapp force-pushed the fix/registries-entry-files branch from adb1d71 to ff3f822 Compare November 12, 2026 09:03
@clhodapp
clhodapp merged commit d45b2bc into main Nov 13, 2026
9 checks passed
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