gen-assemble
A configuration framework that assembles one node set from many layers’ contributions writes the same protocol around the same call every time. gen-assemble is that protocol, extracted once: the contribution union, an identifier convention, structural declarations, and precondition checks over the substrate an assembly depends on. What’s genuinely per-framework is the contribution dimension and the computation over it — gen-assemble owns everything else.
The problem it owns: three defects showed up independently in hand-rolled assembly code, two of
them silent — a library built green against them would have handed a caller a wrong answer with no
diagnostic anywhere. substratePreconditions publishes the properties an assembly depends on, and
an assembly over a substrate failing any of them refuses to evaluate by name rather than continuing
on a base it can’t trust.
Unlike most of the roster, gen-assemble publishes its .lib unapplied — a function of its
substrate rather than a resolved value. This hub supplies that substrate by construction rather
than by convention:
# The substrate the hub hands the three members whose flake `.lib` is published UNAPPLIED. A FUNCTION# OF THE HUB'S OWN `members` BINDINGS — never of `inputs` — so there is one expression per member in# this flake and this file re-derives none of them. `inherit` binds without forcing, so a reader# taking `attrNames` never forces a leaf, which is what lets `ci/` read the supplied key sets# hermetically, the same direction `ci/hub-entry.nix` takes on the standalone root.members: { assemble = { inherit (members) prelude scope algebra; }; delivery = { inherit (members) algebra aspects; }; # ★ gen-inspect's fifth declared dependency, gen-program, is NOT here and cannot be: this file is a # function of `members`, which holds exactly the eighteen roster entries whose `.lib` is published # APPLIED, and `program` is one of the three UNAPPLIED members the fold over this very attrset # produces. gen-inspect therefore declares four formals at this gate and takes gen-program at the # gate that builds its program route, when the fold this file feeds is rewritten to be # self-referential or the dependency arrives another way. inspect = { inherit (members) prelude graph select scope ; }; program = { inherit (members) prelude scope; };}Take it alone
Section titled “Take it alone”assemble = import "${genInputs.gen-assemble}/lib" { inherit (genInputs) prelude scope algebra;};Pass prelude, scope, and algebra yourself — gen-assemble never re-exports a self-resolved
.lib, so nothing is wired for you implicitly. No roster member currently builds on gen-assemble;
it’s meant to be assembled into directly by a framework.
Palettes adapted from Catppuccin (Macchiato) (MIT), Tokyo Night (Apache-2.0), gruvbox (MIT), Catppuccin (Latte) (MIT), Rosé Pine (Dawn) (MIT).