Strata
Every library on the roster declares exactly one stratum. Not zero, not two — one. The declaration lives in a single total map in the hub’s own source, and “total” is not a description, it’s a build-time property: a roster member with no entry there is a build error by design, not a lint that happens to catch it later.
algebra,aspects,assemble,bind,class,delivery,dispatch,graph,identity,inspect,link,memo,merge,prelude,product,program,schema,scope,select,settings,types,view,Each of those twenty-two names is bound to exactly one of five stratum values in
lib/mkGenLibs.nix’s strata map.
Four ranked, one lifecycle exit
Section titled “Four ranked, one lifecycle exit”Four stratum values form an ordered chain: substrate < modules < aspects < framework. The fifth,
retiring, isn’t a layer at all — it’s the state of a library whose content is moving into another
member and off the roster. It sits outside the ranking, because ranking it would mean deciding
where a thing that’s leaving belongs relative to things that are staying, and there’s no coherent
answer to that.
publishedStrata = [ "substrate" "modules" "aspects" "framework"];knownStrata = publishedStrata ++ [ "retiring"];At the current roster’s count: twelve libraries are substrate (the base layer — values, graphs,
selection, evaluation), two are modules (the module system’s checking and merging halves), three
are aspects (the aspect layer, built on the module system), and five are framework (above the
stack rather than a layer of it — nothing may define substrate vocabulary in framework’s terms).
Nothing currently sits in retiring; the bucket exists for when something does, and a library
that’s there stays reachable on the flat roster rather than disappearing the moment it starts to
leave.
The direction of dependence is the law
Section titled “The direction of dependence is the law”No member may declare an input above its own stratum. A substrate library cannot depend on an aspects library; a modules library cannot depend on a framework library. That’s not a style preference — it’s what makes “substrate” mean anything: if a base-layer library could reach up into the aspect layer, there would be no base layer, just a graph of libraries that happens to draw a diagram in one particular order today.
A dedicated check walks that graph on every run. Exactly one upward edge is ruled through as a named exception rather than hidden: gen-schema, substrate by role, declares kinds whose fields are options and so is written in the module system’s language — reaching up into gen-schema’s neighbor, gen-merge, in the modules stratum. The check doesn’t soften the rule to let that edge pass quietly; it prints the exception, entry by entry, on every run.
Keep reading
Section titled “Keep reading”Palettes adapted from Catppuccin (Macchiato) (MIT), Tokyo Night (Apache-2.0), gruvbox (MIT), Catppuccin (Latte) (MIT), Rosé Pine (Dawn) (MIT).