sui-spec 0.1.14

Declarative Lisp-authored specs for CppNix-parity behaviors. Rust types are the hard boundary; Lisp forms are the free-middle authoring surface. Both engines (tree-walker + VM) drive the same spec, so they cannot drift.
docs.rs failed to build sui-spec-0.1.14
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: sui-spec-0.1.12

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.