Skip to main content

Crate sui_spec

Crate sui_spec 

Source
Expand description

sui-spec — declarative Lisp-authored specs for CppNix-parity behaviors.

§Why this crate exists

Every bug we found on the road to drop-in replacement was a spec bug, not an implementation bug. “Unresolved form has env.out = ‘’”, “hash the final form not the unresolved one”, “mask env entries whose names match outputs” — these are statements about CppNix behavior, and they were living inside imperative Rust functions that happened to be duplicated between the tree-walker (sui-eval) and the bytecode VM (sui-bytecode). The copies drifted independently.

This crate is the cure.

§The pattern

Rust is structure and provability. Lisp is transformation, rendering, simulation, and in-flight mutation. The pair can generate each other: a Rust type is the typed border for a Lisp authoring surface; a Lisp spec is the free middle that renders out to any morphism (ATerm bytes, JSON attrsets, probe matrices) a substrate needs.

Every domain below is a #[derive(TataraDomain)] Rust struct (the hard, typed border) paired with a .lisp spec file (the free-middle authoring surface). Interpreters in this crate consume the typed spec and emit the morphism renderings both engines call. Change the Lisp, both engines change together. The tree-walker and the VM cannot diverge because they read the same authored spec.

§Inventory

  • derivation — input-addressed + fixed-output derivation path algorithms. Was: 50 lines of imperative Rust in each of two engines (4 bugs found this session). Now: one .lisp spec and one interpreter.
  • flake — top-level flake result shape policy. Prevents the “leak description / nixConfig” class of bug.
  • probe — single-expression cross-engine parity probes. Includes the probe::Probe type, the original parity_probes.lisp corpus, and the builtin_smoke_probes.lisp corpus (one probe per sui builtin module).
  • rebuild — host-aware multi-stage rebuild parity probes. The typed substrate that lets sui-sweep (and future operator surfaces) shadow a real fleet rebuild end-to-end without ever mutating the system.
  • parity — the parity::ParityCheck trait every typed domain implements, plus parity::ShadowReport / parity::Verdict / parity::ProbeContext. This is the second-site abstraction: solve once, both probe::Probe and rebuild::RebuildProbe ride on it, and the future sui rebuild-shadow subcommand reuses the same trait without re-authoring the sweep loop.
  • exec — typed dual-subprocess runner. NO SHELL. Mandatory timeout. Captured output as a typed struct.
  • sweep — library entry point for the shadow-sweep loop. Both the sui-sweep binary and the sui rebuild-shadow subcommand (future) wrap sweep::run.

More domains will land here as we identify them. Rule of thumb: if the body of a function is “here is what CppNix does”, that function belongs in this crate as a spec + interpreter, not in the engine.

Re-exports§

pub use spec_trait::HasName;
pub use spec_trait::Spec;
pub use error::SpecError;
pub use parity::ParityCheck;
pub use parity::ProbeContext;
pub use parity::ProbeKind;
pub use parity::ShadowReport;
pub use parity::Verdict;
pub use sweep::Corpus;
pub use sweep::SweepConfig;

Modules§

activation_script
Activation script generation — typed border for the cppnix switch-to-configuration / darwin-rebuild / home-manager activate script generators.
ast_evaluator
Minimum-viable tree-walking evaluator over AstGraph — the engine that drives the module-system solver’s BodyEvaluator impl today.
ast_graph
L1 AstGraph — the parsed, canonicalized, content-addressed form of a single Nix expression (one .nix file or one inline expression).
catalog
Substrate self-description — the typed catalog of every authored sui-spec domain.
cli
Typed builders for sui and nix CLI invocations.
cli_coverage
cli_coverage — typed self-description of sui’s nix-replacement progress.
coercion
Typed border for nix’s value → string coercion at the eval→drv boundary — the complement of the laziness domain. Where laziness names when/how a thunk forces + shares, coercion names how a forced value becomes a string/path, and what store-context it carries. Together they are why derivations byte-match nix.
derivation
Derivation path computation — the CppNix algorithm as Lisp data.
dockerfile
Typed border for a REGULAR Dockerfile (BuildKit-syntax, not a Nix derivation) digested into a content-addressed derivation graph.
error
Errors produced while loading or interpreting sui-spec specs.
eval_cache
Typed border for the evaluation cache.
exec
Typed dual-subprocess runner — the shared substrate every ParityCheck rides on.
fetcher
Typed border for nix’s ingest layer — builtins.fetchurl, fetchTarball, fetchGit, fetchTree, path.
flake
Flake result shape — declarative policy for getFlake / callFlake output assembly. CppNix parity, authored as Lisp data.
gc
Typed border for the nix store garbage collector.
hash
Typed border for nix’s hash representation.
laziness
Typed border for nix’s laziness / thunk-sharing / demand-order model — the one core evaluator algorithm that, until now, lived only as imperative Rust in sui-eval/src/{value,eval,lazy}.rs and was hand-coded twice (the tree-walker + the bytecode VM). That double-authoring is exactly why the two engines diverge on byte parity: the VM historically defers string-context while the tree-walker tracks it, and thunk sharing is not referential, so evaluation order can change a derivation (impossible in nix).
loader
Generic spec loader — thin wrapper around tatara_lisp::compile_typed.
lock_file
Typed border for flake.lock — the on-disk representation of resolved flake inputs.
lockfile_graph
L1 LockfileGraph — the parsed, follows-resolved, content-addressed representation of a flake.lock.
module_compiler
Module-system compiler — extracts the typed ModuleNode shape from a raw AstGraph.
module_graph
L4 ModuleGraph — typed IR for a NixOS/nix-darwin/home-manager module system, compiled into worker/wrapper-split assignment closures with slice-keyed re-firing.
module_solver
L4 module-system solver — slice-keyed re-firing over a compiled ModuleGraph.
module_system
The Nix module system — typed border for the option-merge lattice.
nar
Typed border for the Nix Archive (.nar) format.
narinfo
Typed border for the narinfo file format.
nix_replacement_coverage
Nix-replacement coverage catalog — one row per Nix workload sui must cover. Authored as Lisp forms in specs/nix_replacement_coverage.lisp, projected to typed Rust records here.
operator_view
OperatorView — the shape every operator-facing introspection mode shares.
parity
The ParityCheck trait — every typed parity question rides on it.
probe
Parity probes — each a typed question of the form “does sui agree with CppNix on this expression?”.
profile
Typed border for nix-env / nix profile generations.
realisation
Typed border for content-addressed derivation realisations.
rebuild
(defrebuild-probe …) — host-aware multi-stage rebuild parity probes.
registry
Typed border for the flake registry — the lookup that resolves short input refs (nixpkgs, github:owner/repo) to concrete fromto mappings.
sandbox
Typed border for the build sandbox.
spec_trait
The Spec trait — the unifying abstraction across every authored sui-spec domain.
store_analyze
Typed analysis over an observed store.
store_diff
Typed diff between two ParsedNar trees.
store_inventory
Typed in-memory model of a Nix store.
store_layout
Typed border for the /nix/store directory layout.
store_ops
Typed store-operation primitives — parse, transform, query.
store_query
Typed query AST over the typed store substrate.
store_recipe
Declarative pipeline composition for store operations.
store_transform
Typed transformation AST over ParsedNar trees.
style
Nord-palette styled output for sui CLI surfaces.
substituter
Typed border for the binary-cache substitution protocol — cache.nixos.org, S3-backed Attic, local file-system caches.
sweep
Library entry point for the shadow-sweep loop.
trust_model
Typed border for the nix trust model.
worker_protocol
Typed border for the nix-daemon worker protocol.