skip to content

Terminology

One vocabulary runs through every page in this documentation, grounded in specific academic results rather than invented for the occasion — Knuth’s attribute grammars, Néron’s scope graphs, well-founded semantics for logic programs with negation. Every term below means the same thing on every page it appears on. This is the fast path to a definition; the hub’s own TERMINOLOGY.md carries the full per-library vocabulary, with a citation for every term, including everything below that’s specific enough to one library that it doesn’t earn a place here.

Node — A position with attributes and incident labelled edges: an identity, some attributes (declared or computed), and the edges touching it. There is exactly one node notion for the whole substrate. See the graph model.

Edge — A labelled relationship between two nodes, carrying a label and no interpreted content. Anything that needs to carry content is represented as a node instead. See the graph model.

Kind — A schema-level datum a node carries, not a partition of the substrate. aspect and entity are ordinary gen-declared kinds, not cases the substrate treats specially. See the graph model.

Identity (hashIdentity) — The one identity-minting authority for the whole ecosystem: a kind-tagged canonical hash. The substrate refuses rather than inventing an identity it cannot mint totally. See the graph model.

Binding node — A reified relation, identified by which relation it is and what it relates, used whenever a relationship needs to carry content that a plain edge can’t. See the graph model.

Scope graph — The graph a name resolves against, kept separate from whatever tree produced it. Query combinators resolve names over it with import/parent specificity. See gen-scope.

Attribute — A computed value on a node, demand-driven and memoized by Nix’s own laziness — the classical inherited / synthesized distinction from attribute-grammar theory. See gen-scope.

Roster — The twenty-two libraries lib/mkGenLibs.nix names as required arguments. Total and explicit: a library not named there does not wire into the hub, full stop. See the roster.

Stratum — One of four ordered layers (substrate < modules < aspects < framework) plus a fifth, unordered lifecycle state (retiring) for a member on its way off the roster. Every member declares exactly one. See strata.

Sole evaluator — gen-scope, the one library in the roster permitted to evaluate at all. Every other library, including gen-inspect, implements no semantics of its own and never evaluates. See execution.

Incremental plane — gen-memo, the one decision layer over the evaluator. It never evaluates, only decides reuse, and its definition is a byte-parity oracle against a cold run rather than a description of what it does internally. See execution.

Byte-parity oracle — The bar gen-memo is defined against: a plane output must be byte-identical to what a full, cold evaluation would have produced. A plane that accumulates its own evaluation state to get there has failed by construction, not merely underperformed. See execution.

Assembly — The step that unions a framework’s contributions commutatively — shapes merge, content folds — and hands the result to the one graph, without ever evaluating while doing it. See gen-assemble.

Policy — A rule in a logic program, not a callback or a hook. The edges a policy produces are the program’s model: the atoms that follow from what’s declared. See policies.

Program — What gen-program turns a framework’s policy declarations into: every rule becomes a head, a positive body, a negative body, and the relata the head relates. gen-scope then solves it. See policies.

Stratification — Solving a program stratum by stratum, so a rule can never depend on the very fact it’s still deciding. A cycle through negation can’t be expressed in the first place, because a consumed query only ever observes already-materialized declarations, never the still-evolving relation. See policies.

Well-founded model — The result of solving a stratified program with negation. An atom whose truth depends on itself through negation comes out UNDEFINED — a named third value, not an error and not an arbitrary pick between true and false. See policies.

Dynamic edge — An admitted atom from a policy program, joining the one graph with its predicate as the label and its relata as the endpoints. It keeps that label, so it is never mistakable for a declared edge just by looking at the graph. See policies.

View — A named, materialized query result over the selector algebra. A projection has a name and a defining query, or it is not a view.

Movement — Content moving between graph positions, expressed as two ends of one idea: a collector receiving content by query, and a broadcaster declaring it available. Neither copies content by hand.

Collector — A receiver-rooted query: what a position gathers from the graph around it.

Broadcaster — A producer’s declaration paired with a standing query: what a position makes available to whatever asks for it.

Aspect — A submodule with structural identity and freeform content — gen’s composable configuration unit, and, per the graph model, an ordinary declared kind like any other. See gen-aspects.

Entity — A structural kind a framework declares for the things its domain is actually about — a host, a user. It follows the same rule an aspect does: the substrate does not read it specially.

Trait — The aspect type: one type, with dispatch happening in merge rather than in a type hierarchy. See gen-aspects.

Class — A registered output target — nixos, darwin, homeManager, or a framework’s own. Content exits the scope graph into external evaluation through a class. Not to be confused with gen-class’s class-share, an unrelated mechanism for reusing computation across nodes with the same shape — see gen-class.

Terminal — The target-owned evaluator a delivery class’s collected content is finally handed to — a nixosSystem, a darwinSystem, or a framework’s own.

Two-plane split — The composition plane (pure, no nixpkgs.lib) and the terminal plane (nixpkgs), with exactly one sanctioned crossing between them.

Value-injection — Composing purely, then injecting resolved config values — never gen types — into a consumer’s nixpkgs evaluation; only values cross the one sanctioned crossing, held under a declared interim until every crossing site meets the condition that closes it, so the boundary is expected to tighten, not to stay where it is indefinitely.

Selector — A { __sel = tag; ... } attrset matched against an accessor context — gen’s pattern matching over graph positions, closely modelled on CSS selectors. See gen-select.

Rule — A guarded transformation unit: a condition, an action producer, and an identity. See gen-dispatch.

Settings layer — An ordered, least-to-most-specific contribution to a resolved settings value, folded with a per-field provenance chain. See gen-settings.

palette
dark
light
↑↓ select apply esc close

Palettes adapted from Catppuccin (Macchiato) (MIT), Tokyo Night (Apache-2.0), gruvbox (MIT), Catppuccin (Latte) (MIT), Rosé Pine (Dawn) (MIT).