Split the flake check gate into per-machine and per-check runs #34
No reviewers
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/archetypes!34
Loading…
Reference in a new issue
No description provided.
Delete branch "agent/check-gate-split"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This replaces the routine
nix flake checkgate with./check.sh, a split gate that runs the same currentnixosConfigurationsandcheckscoverage onenixprocess at a time. The reason is memory pressure: the native whole-flake command evaluates all machines and checks in one process, andruntime-module-selectionalready dominates the peak. This PR is a pressure valve forallod/archetypes#31, not the destination.The repair pass keeps Bash as a scheduler and keeps Nix responsible for flake semantics. Machine and check names are enumerated from the flake as JSON records, not delimiter text, and Nix constructs quoted installable suffixes for discovered names. Ordinary names stay on normal flake installables; names containing control characters that the installable parser cannot safely represent fall back to a Nix expression that dereferences the JSON record structurally. The gate also refuses any top-level output outside this repo's explicit allow-list: handled outputs
checksandnixosConfigurations, plus passive repo surfaceslib,vmFacts, andprofilesSource. Those passive surfaces are forced as their own steps so throwing top-level outputs fail here the same way they fail under nativenix flake check.Coverage
./check.shforces each allowed passive top-level output to WHNF. It forces eachnixosConfigurations.<name>.config.system.build.toplevel, verifies that value is a derivation, and then forcesdrvPath. It builds each check for the current system withnix build --no-link. Foreign-system checks are evaluated todrvPathand reported as evaluated but not built, which is more than nativenix flake checkdoes without--all-systems. The gate keeps going after a failed step and exits non-zero with a failure summary.The script refuses to report success if it found no machine and no check to run. Passive top-level output forcing does not make a repo gate meaningful by itself. The script also refuses invalid
checks.<system>names that do not contain-, matching Nix'scheckSystemNameshape rule.Risk
The residual risk is that this repo now carries a shell wrapper for behavior normally owned by Nix. The wrapper is deliberately narrow: Bash stores JSON records, schedules isolated Nix invocations, and aggregates status; Nix still owns flake evaluation, derivation checks, passive-output forcing, and escaped attr-path construction for ordinary discovered names. The long-term fix remains
allod/archetypes#31: reduce or move the expensive guest-behavior assertions until nativenix flake checkfits the dev VM again, then removecheck.sh.The guest-behavior migration is tracked separately in
allod/vm#6, as part ofallod/strategy#20. Move those assertions into minimalallod/vmfixtures in coherent groups, proveallod/vmreports matching sabotage before deleting the heavier archetypes reporter, and keeparchetypesfocused on runtime selection and wiring.Validation
./check-selftest.shpasses. It now runs ten zero-input fixture flakes covering successful runs, checks-only flakes, dotted machine/check names, tab-containing names that look like injected records, throwing passive outputs, failed machine/check steps, no-op runs, invalidcheckssystem names, unhandled validated outputs such aspackages, and unknown typo-like outputs such aschekcs../check.shpasses on the real flake: all 17 steps passed, including the three passive top-level outputs plus the existing 14 machine/check steps.nix shell nixpkgs#shellcheck -c shellcheck --severity=style check.sh check-selftest.shis clean.git diff --checkis clean.Refs allod/strategy#20
Refs allod/archetypes#31
Refs allod/vm#6
7042f0a054toc25f165bd3@ -55,3 +55,4 @@nix build .#nixosConfigurations.nexus.config.system.build.toplevel --no-link````./check.sh` is what to run instead of `nix flake check`. The whole-flakemost of the paragraph is unnecessary. just say the memory requirements are too high so we're breaking up the flake check. exact measurements get stale fast and also nobody cares. they ain't gonna read all that mess
Review concerns:
check.shlosesnix flake check's unknown-output warning path. The unhandled-output guard only considers names in the hardcodedvalidatedset (check.sh:87-89), so a top-level typo likechekcsis silently ignored by./check.shwhilenix flake check --no-buildemitswarning: unknown flake output 'chekcs'. Since this script becomes the human gate, I would either fail on every top-level output outside an explicit allow-list (checks,nixosConfigurations,lib,vmFacts,profilesSource) or at least preserve the warning. Failing loud is cleaner here.The discovered machine/check names are later spliced into CLI attr paths (
check.sh:144,check.sh:153,check.sh:159). That is not equivalent to Nix's structural traversal for all valid attr names:checks.x86_64-linux."foo.bar"passes nativenix flake check --no-build, but./check.shtries to buildchecks.x86_64-linux.foo.barand fails. This repo's current names are plain enough, so it is not breaking today's gate, but it is a fidelity gap in the "read names out of the flake" design. A more robust shape is to keep dereferencing inside Nix withbuiltins.getAttrusing env/json inputs, and let Bash only sequence independent Nix invocations and aggregate statuses.Design-wise, I do not object to a Bash scheduler as a pragmatic memory workaround, because the load-bearing evaluation/build work still stays in Nix. But I would keep the Bash surface deliberately thin and self-tested as a compatibility shim, not let it become a second implementation of flake-check semantics. Long-term, the cleaner fix is still to lower/split
runtime-module-selectionenough that nativenix flake checkfits again.Owner direction for the repair pass: keep this PR open, but tighten the split gate so Bash is only the scheduler and Nix owns semantic lookup/validation. Repair the two review findings by failing loudly on unknown top-level outputs outside this repo's explicit allow-list and by avoiding CLI attr-path interpolation for discovered machine/check names. Add self-test coverage for both cases. Also trim the README explanation per the inline comment.
Longer-term strategy stays separate: move guest-behavior assertions into minimal
allod/vmfixtures in coherent groups, and removecheck.shonce nativenix flake checkfits within the dev VM headroom again.Second read-only review pass found two blockers against the final repaired diff:
check.shcan misparse valid attribute names containing tabs. Enumeration emits raw tab-delimited records (check.sh:100,check.sh:109), and Bash parses them withIFS=$'\t' read -r kind first second third(check.sh:145-150). A valid machine name likebad<TAB>nixosConfigurations."good".config.system.build.toplevelmakesmachine_attrsreceive the injectednixosConfigurations."good"...field while the real quoted suffix lands in the discarded fourth field. Verified with a throwaway flake:./check.shrangoodtwice and passed while nativenix flake check --no-buildfailed on the tabbed machine's throwing toplevel. Use a structured/escaped record format rather than raw TSV.check.shdoes not force allowed passive outputs that nativenix flake checkstill forces. The gate allow-listslib,vmFacts, andprofilesSourceas passive outputs (check.sh:83-86) and then only enumerates machines/checks (check.sh:102-110). Verified withprofilesSource = throw "profilesSource throws on purpose":./check.shpassed after building the check, whilenix flake check --no-buildfailed while checkingprofilesSource. Add explicit WHNF forcing for allowed passive outputs, with a self-test fixture that proves a throwing passive output turns the gate red.The ordinary dotted-name repair and the final return to normal flake installables look good. Failure aggregation, invalid
checks.<system>handling, and the no-steps guard also looked sound in this pass.Owner direction: fix the two blockers from the second review pass. Replace raw TSV enumeration with a structured or escaped format so valid attribute names containing tabs/newlines cannot inject fields, and force the allowed passive outputs (
lib,vmFacts,profilesSource) so this gate preserves nativenix flake check's top-level-output forcing. Add self-test coverage for both repairs.Fixed the two blockers from the second review pass in
7886463.jq, so tabs/newlines in attr names cannot inject fields. Ordinary discovered names still run through normal flake installables; control-character names fall back to structural Nix lookup from the JSON record.lib,vmFacts, andprofilesSource, forced to WHNF withbuiltins.seq, so throwing passive outputs now fail the wrapper like nativenix flake check.tabbed-namesandpassive-throw.Validation:
./check-selftest.shpassed;./check.shpassed all 17 real-flake steps; ShellCheck style run passed;git diff --checkpassed.