Skip to content

Name gathered checks as exported configurations are named - #160

Merged
clhodapp merged 2 commits into
mainfrom
feat/check-names-by-integration
Nov 14, 2026
Merged

clhodapp merged 2 commits into
mainfrom
feat/check-names-by-integration

Conversation

@clhodapp

@clhodapp clhodapp commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

A caisson top gathers the checks of every configuration declared inside it into checks.<system>. This change names those checks the way the exports name configurations in an output attribute set, so a NixOS configuration and a system-manager configuration declared under the same name no longer publish the same check name.

The rule

Each gathered check has a path of { type, name } segments:

  1. the configurations from the caisson top down to the configuration that declares the check, with the integration as type, flake-parts configurations included and systems left out (as the exports drop the systems in an output keyed by system);
  2. then { type = "check"; name = <check name>; }.

The published name is caisson-core.elide over the paths of the checks gathered for every system, each path counted once, written by displayName:

  • a check whose name no other check gathered for any system has keeps it bare: the check toplevel of the only NixOS configuration is toplevel;
  • checks of the same name gain the segment where their paths fork, the segment nearest the caisson top that tells them apart, joined with /: the checks toplevel of the NixOS configurations nas-1 and nas-2 are nas-1/toplevel and nas-2/toplevel;
  • a segment is written type/name where the branches at that fork hold the same name under different integrations: a NixOS configuration and a system-manager configuration both named box give nixos/box/toplevel and system-manager/box/toplevel;
  • checks that still share a name are refused for each system, with their paths, with the error the exports give: checks.x86_64-linux: these checks would be published under the same name, ....

A check has the same name under every system it is gathered for. The NixOS configuration nas-1 evaluated for x86_64-linux and aarch64-linux, beside a NixOS configuration arm inside the structural configuration lab evaluated for aarch64-linux alone, gives nas-1/toplevel under both systems and lab/toplevel under aarch64-linux.

The exports name an output keyed by system the same way: for an export whose exportsTo says bySystem, such as packages, elide runs once over the paths of every system, so an entry has the same name under each system. Outputs not keyed by system are named as on main.

caisson-core.elide is used unchanged: the paths are deduplicated before the call, and two members with equal paths under one system get the same name, which the refusal catches. In lib-overlays/integrations/default.nix, namedByPath pairs members with their names and refuseShared refuses members that share a name. publicationOf and gatheredChecksOf both call them. The check record keeps from.namePath, the address of the declaring configuration under children (systems included), and adds from.check, the name of the check there, so the full path of every check is in the record.

Measured names

caisson.manifest.checkRecord of each flake, evaluated with --override-input caisson set to main (3d9e52c) and then to this branch, on workspace main. Both flakes evaluate their configurations for x86_64-linux alone, so every check is under x86_64-linux.

ch-personal-machines

main this branch declared by
aacs-cat-package aacs-cat-package the caisson top
am2r-package am2r-package the caisson top
builder-1-builder-1-toplevel builder-1/toplevel NixOS builder-1 inside caisson-disko builder-1
builder-2-builder-2-toplevel builder-2/toplevel likewise for builder-2
builder-3-builder-3-toplevel builder-3/toplevel likewise for builder-3
builder-4-builder-4-toplevel builder-4/toplevel likewise for builder-4
builder-5-builder-5-toplevel builder-5/toplevel likewise for builder-5
builder-6-builder-6-toplevel builder-6/toplevel likewise for builder-6
chris-desktop-2-chris-desktop-2-chris-activation chris-desktop-2/activation home-manager chris inside NixOS chris-desktop-2 inside caisson-facter chris-desktop-2
chris-desktop-2-chris-desktop-2-toplevel chris-desktop-2/toplevel NixOS chris-desktop-2 inside caisson-facter chris-desktop-2
chris-laptop-1-chris-activation chris-laptop-1/activation home-manager chris inside NixOS chris-laptop-1
chris-laptop-1-toplevel chris-laptop-1/toplevel NixOS chris-laptop-1
chris-tablet-1-chris-activation chris-tablet-1/activation home-manager chris inside NixOS chris-tablet-1
chris-tablet-1-toplevel chris-tablet-1/toplevel NixOS chris-tablet-1
colmenaHive-nas-1-toplevel colmenaHive/nas-1/toplevel NixOS nas-1 inside caisson-colmena colmenaHive
colmenaHive-router-primary-router-primary-toplevel colmenaHive/router-primary/toplevel NixOS router-primary inside caisson-disko router-primary inside caisson-colmena colmenaHive
eval-weight-report-package eval-weight-report-package the caisson top
greeter-display-test-toplevel greeter-display-test/toplevel NixOS greeter-display-test
hpt-cli-package hpt-cli-package the caisson top
installer-toplevel installer/toplevel NixOS installer
jellium-desktop-package jellium-desktop-package the caisson top
recovery-smoke-recovery-smoke-toplevel recovery-smoke/toplevel NixOS recovery-smoke inside caisson-disko recovery-smoke
registries registries the caisson top
steam-deck-1-toplevel steam-deck-1/toplevel NixOS steam-deck-1

The toplevel checks share a name, and so do the activation checks, so each gains the first segment of its path; the paths of the checks inside colmenaHive fork again below it. A check name that appears once, such as each <name>-package, stays bare.

ch-emacs-config

No name changes: emacs-package, emacs-package-manifest-package, emacs-pgtk-package and registries are declared by the caisson top, and each name appears once.

A nixos-test configuration inside a NixOS configuration

The test smoke declared inside the NixOS configuration nas-1 (tests/nixos-test-vm) was nas-1-smoke-test. Its check test is the only check of that name there, so it is now test, and its record holds from.check = "test" and from.namePath system x86_64-linux / nixos nas-1 / system x86_64-linux / nixos-test smoke.

caisson

The checks of caisson are declared by the flake-parts configuration checks (configs/flake/checks) inside the flake-parts caisson top, and registries by the caisson top. Every name appears once, so all stay bare: the 46 names under checks.x86_64-linux and darwin-system under checks.aarch64-darwin are the same on main (e22972c) and on this branch.

nix-unit configurations

The nix-unit test (tests/nix-unit) declares the nix-unit configurations passing and failing, and the default check of each is unit. The checks share their name, so they are passing/unit and failing/unit under both systems; on main they are passing-unit and failing-unit.

Tests

  • The tests that list gathered names (tests/unit/lib-overlays.nix, tests/pinned-world/default.nix, tests/nixos-test-vm) read the names elide gives, and the record tests read from.check. In the pinned-world fixture, the check smoke of nas-1 is nas-1/smoke under both systems.
  • A new unit test publishes an output keyed by system whose treefmt configuration a inside lab collides under x86_64-linux alone, and is lab/a under both systems.
  • The volatile-check test from Build volatile checks as fixed-output derivations with lib.caisson.mkVolatileCheck #159 reads the check reaches under its name, and the nix-unit test from Add the nix-unit integration #157 reads passing/unit and failing/unit.
  • The system-manager configuration registered of the registered world turns its toplevel check back on; Declare the default checks of the integrations and the check registries #154 had turned it off to avoid the clash with the NixOS configuration registered. The new pinned-world test sameNameInDifferentIntegrationsPublishesBothChecks reads nixos/registered/toplevel and system-manager/registered/toplevel, each the toplevel of its configuration.
  • The clash tests declare a check on the caisson top named nas-1/smoke, the name elide gives the check smoke of the NixOS configuration nas-1 beside another smoke; the unit test matches the error and both paths.

Checks run

Six checks under checks.x86_64-linux have a different drvPath from main (e22972c): argument-errors, deferred-errors, eval-weight, nix-unit, nix-unit-integration and treefmt. All six pass locally. pinned-world passes too; its suite is forced while the checks evaluate. nixos-test-vm builds the same derivation as on main and reads it under its new name.

topside

topside main (c845901) runs a check whose name holds /: over a fixture flake with flake-parts configurations a and b that each declare smoke, topside checks lists a/smoke and b/smoke, and topside check a/smoke builds it and reports it passed. topside builds a check by its drvPath, so the name never appears in an installable.

🤖 Generated with Claude Code

@clhodapp clhodapp self-assigned this Nov 12, 2026
@clhodapp
clhodapp force-pushed the feat/check-names-by-integration branch from 5e53350 to 593426e Compare November 13, 2026 07:55
@clhodapp clhodapp changed the title Put the declaring integration into the names of gathered checks Name gathered checks as exported configurations are named Nov 13, 2026
@clhodapp
clhodapp force-pushed the feat/check-names-by-integration branch from 593426e to 0b5f4e5 Compare November 13, 2026 18:05
@clhodapp
clhodapp marked this pull request as ready for review November 13, 2026 18:05
clhodapp and others added 2 commits November 13, 2026 19:56
A caisson top names the checks it gathers under `checks.<system>`
as it names the configurations in an output keyed by system: each
check has a path, the configurations from the caisson top down to the
configuration that declares it as `{ type, name }` segments without
the systems, then the check, and the names are `caisson-core.elide`
over the paths, written by `displayName`. A check whose name is alone
keeps it, and checks of the same name gain the segments that tell them
apart: `nas-1/toplevel` and `nas-2/toplevel`, or `nixos/box/toplevel`
and `system-manager/box/toplevel` for a NixOS configuration and a
system-manager configuration both named `box`.

In an output keyed by system, the checks output and an export whose
`exportsTo` says `bySystem`, `elide` runs once over the paths of every
system, each path counted once, so an entry has the same name under
each system it appears under. Entries that still share a name are
refused for each system, with the error the exports give.

`namedByPath` pairs members with their names and `refuseShared`
refuses members that share a name; the exports and the gathered
checks both use them. The check record adds `from.check`, the name of
the check in the configuration that declares it, beside
`from.namePath`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d` toplevels

The tests that list gathered checks read the names `elide` gives over
the checks of every system, the nix-unit test among them: the check
`unit` of the nix-unit configurations `passing` and `failing` is
`passing/unit` and `failing/unit`. The system-manager configuration
`registered` of the registered world turns its `toplevel` check back
on, and a new test reads `nixos/registered/toplevel` and
`system-manager/registered/toplevel`. A new unit test publishes an
output keyed by system whose entry collides under one system alone and
has the same name under both. The clash tests declare a check on the
caisson top under the name `elide` gives a check of a NixOS
configuration, `nas-1/smoke`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@clhodapp
clhodapp force-pushed the feat/check-names-by-integration branch from 6f908ff to 01cb618 Compare November 14, 2026 04:07
@clhodapp
clhodapp merged commit 085f53c into main Nov 14, 2026
10 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