Collectivenix fleet

30 machines · 4 platform classes · 1 registry

Reference

Development

Collective configures the machines it is developed on, so a careless change can break the environment that would fix it. The working rule is to evaluate and test freely, and leave activation to the operator.

Ground rules

Never switch for someoneAgents and contributors do not run cltv switch, nixos-rebuild switch, darwin-rebuild switch, nix-on-droid switch or a raw nix flake update. Switches depend on SSH agents, private inputs, tokens and work steps that only the operator's session has. Say what changed and that a switch is needed.

Evaluate instead of switching

# a system option on this machine or anothercltv nix eval system -e 'config.services.openssh.enable'cltv nix eval system -e 'config.environment.systemPackages' --system-name NAME --system-type nixos# a Home Manager optioncltv nix eval home -e 'config.programs.zsh.enable'# anything in the flake's outputscltv nix eval outputs -e 'registry.lists'# does the whole machine still evaluate?nix eval --raw .#nixosConfigurations.NAME.config.system.build.toplevel.drvPath# a library expressionnix eval --json .#lib.x86_64-linux --apply 'L: L.dispatch { int = x: x + 1; } 41'42

cltv repl --flake opens nix repl with the system's environment preloaded, and cltv repl -p opens one against the working copy of collective-public. cltv script run --name NAME runs an edited cltv command without a switch, and cltv run pkg#bin runs a package from the configured set.

Tests

Tests sit next to what they test and run without a switch.

SuiteWhereRun
collective-libInline _tests in 21 library files, plus nix-reflect's suitesCOLLECTIVE_PUBLIC_DIR=$PWD/collective-public ./collective-public/scripts/run-tests
One library testAny named test./collective-public/scripts/run-test module name, or debug-test for traces
Public modulesModule suites in collective-public./collective-public/scripts/run-module-tests
Flake checksRunner sandbox contract (evaluated from a real devbox), supervisord exec canary, release and VM workflow contracts, browser VM receiptsnix flake check, or nix build .#checks.system.name
Rendered behaviour12 Nix tests in tests/ that render module output (displays, gestures, audio, Tailscale on Android, handheld power)Per file, passing Collective's locked nixpkgs or its lib
Python23 test files in tests/, 13 in scripts/python3 -m unittest discover -s tests -p 'test_*.py' -v
Deployed helpersAbout thirty shell, Python and PowerShell tests for runner, cache and devbox helpersEach file directly, e.g. bash modules/tests/github-runner-min-lifetime-test.sh

The deployed-helper pattern matters: when a shell script is embedded in a module, the module reads it from a file with readFile rather than inlining it, and a test sources the same file. The tested code is the deployed code.

What runs where

WorkflowTriggerDoes
Build & Cache CollectiveVersion tags, weekly, manualBuilds machine closures on self-hosted runners and fills the caches
FlakeHub (parallel to Attic)Push to mainBuilds the prebuilt machines' closures and pushes them to FlakeHub Cache
PagesChanges to site/ on mainValidates and publishes this site
MicroVM buildsManual and on changeBuild and promote the browser-bootable VM bundles

The scheduled prebuilds on cache nodes are not CI: they run as services on the nodes (see Delivery). Nothing gates a pull request automatically, so run the relevant tests and evaluations before merging.

Conventions

Formatting
nix fmt runs alejandra.
Modules
Options under a clear prefix, declared with the library's helpers (mkEnable, mkDefaultOption); configuration behind mkIf cfg.enable; platform differences through systemType.switch, not machine names.
Packages
A flake input, an overlay entry and a bootstrap category; never a second delivery path (see Architecture).
Machines
Only machine-specific settings in machines/name/; registry first, and explicit lists between their markers.
Live configuration
Anything tools edit while running goes in standalone/, linked out of the store.
Public code
Reusable modules and the library go in collective-public/, which is published to its own repository.
Incidents
A fix to a production failure comes with a runbook in docs/runbooks/: the evidence, the change and how to validate it.
Agents
Repository instructions live in AGENTS.md; reusable procedures are skills in plugins/ and standalone/pi/skills.

This site

The site's source is in site/: hand-written HTML whose shared parts are filled in by scripts/site/build.py. Drawings come from scripts/site/figures.py, and the CLI reference from scripts/site/cli-help.sh. scripts/check-site.py checks structure, links and budgets, and refuses any machine name from the registry, address, tailnet name or login before the site can be published.

python3 scripts/site/build.pypython3 scripts/check-site.py