sui-eval 0.1.206

Clean-room Nix language evaluator — lazy tree-walker + bytecode VM with construction-guaranteed Lazy<T>
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
//! Layer 15: System configuration evaluation parity.
//!
//! Progressive tests against ~/code/github/pleme-io/nix system configs.
//! These are discovery tests -- they report what works and what doesn't
//! without hard-asserting on operations that depend on full flake evaluation
//! infrastructure (network fetchTree, nixpkgs import, etc.).
//!
//! # READ THIS BEFORE CITING THIS FILE AS EVIDENCE (2026-08-07)
//!
//! **Every test here no-ops unless `SUI_TEST_ONLINE` is set and
//! `nix-instantiate` is on PATH.** `common::skip_if_offline` returns early,
//! the body never runs, and libtest prints `ok` — so a default
//! `cargo test -p sui-eval` reports these as **passed while measuring
//! nothing**. That is the single most dangerous shape an instrument can
//! have: it manufactures coverage out of a missing precondition.
//!
//! To actually measure parity:
//!
//! ```sh
//! SUI_TEST_ONLINE=1 cargo test -p sui-eval --test system_eval_parity -- --nocapture
//! ```
//!
//! When they DO run, six of the seven assert. The seventh
//! (`nix_repo_eval_no_crash`) asserted nothing at all until 2026-08-07 —
//! it printed `EXPECTED FAILURE (for now)` and returned green on both
//! outcomes, so it could not distinguish "sui still cannot evaluate the
//! fleet's system configs" from "sui now can". It is a characterization
//! tripwire now; see its own doc comment for why that direction is right.
//!
//! Context: `theory/BALIZA.md` phase 0a — truth the instruments before
//! believing anything downstream of them.

mod common;

use std::path::PathBuf;

fn nix_repo() -> PathBuf {
    common::pleme_io_root().join("nix")
}

/// Level 1: characterization tripwire on whether sui can evaluate the
/// fleet's own nix repo.
///
/// **This test used to assert nothing.** Both arms of the match printed and
/// returned green — `SUCCESS` on Ok, `EXPECTED FAILURE (for now)` with the
/// literal comment `// Don't assert -- this is informational` on Err. So it
/// reported the same verdict whether sui had just gained the single most
/// load-bearing capability in `theory/BALIZA.md` or lost it.
///
/// It is a tripwire now, and it deliberately fires on **success**, which is
/// worth explaining because it looks backwards. Per `BALIZA.md` §III,
/// "sui has completed a system-toplevel eval" is **ABSENT — zero recorded
/// instances, ever** (`sui/docs/SUI-EQUIVALENCE.md:325,626`: cid eval OOMs,
/// killed at 4264 s against nix's 107 s). Asserting `Ok` would pin a
/// permanent red that everyone learns to ignore; asserting the *known
/// state* means the day sui can evaluate the nix repo, CI says so out loud
/// instead of a `println!` scrolling past in a `--nocapture` run nobody
/// reads.
///
/// The same shape as the nix repo's `fleet-rustc-witness`: a tripwire, not
/// a pin. The measurement may move whenever it likes — it may not move
/// *unacknowledged*. When it fires, delete the tripwire and land the
/// positive assertion in the same commit.
#[test]
fn nix_repo_eval_no_crash() {
    if common::skip_if_offline("system_eval") {
        return;
    }
    let dir = nix_repo();
    if !dir.join("flake.nix").exists() {
        println!("skip: nix repo not found at {}", dir.display());
        return;
    }

    println!("evaluating {}", dir.display());
    match sui_eval::builtins::evaluate_flake(&dir) {
        Ok(v) => {
            // Report what top-level keys exist, so the operator who trips
            // this has the evidence in hand rather than having to re-run.
            if let sui_eval::value::Value::Attrs(ref attrs) = v {
                let keys: Vec<String> = attrs.keys().collect();
                println!("top-level keys: {keys:?}");
            }
            panic!(
                "TRIPWIRE: sui evaluated the pleme-io/nix flake. This is GOOD NEWS \
                 and the test is red on purpose — theory/BALIZA.md §III records \
                 system-toplevel eval as ABSENT (zero recorded instances, ever), \
                 and phases 8/9/10 are written on that premise. Re-measure, update \
                 BALIZA.md §III, then replace this tripwire with the positive \
                 assertion in the same commit."
            );
        }
        Err(e) => {
            // The recorded state as of 2026-08-07. Not an assertion of
            // desire — an assertion of fact, so the fact cannot change in
            // silence.
            println!("still absent (expected): {e}");
        }
    }
}

/// Level 2: darwinConfigurations key exists
#[test]
fn nix_repo_has_darwin_configurations() {
    if common::skip_if_offline("system_eval_darwin") {
        return;
    }
    let dir = nix_repo();
    if !dir.join("flake.nix").exists() {
        return;
    }

    let result = match sui_eval::builtins::evaluate_flake(&dir) {
        Ok(v) => v,
        Err(e) => {
            println!("eval failed: {e}");
            return;
        }
    };

    if let sui_eval::value::Value::Attrs(ref attrs) = result {
        assert!(
            attrs.contains_key("darwinConfigurations"),
            "flake output should have darwinConfigurations"
        );
        println!("darwinConfigurations found");

        // Try to navigate into it
        if let Some(dc) = attrs.get("darwinConfigurations") {
            let forced = sui_eval::eval::force_value(dc);
            match forced {
                Ok(sui_eval::value::Value::Attrs(ref dc_attrs)) => {
                    let hosts: Vec<String> = dc_attrs.keys().collect();
                    println!("hosts: {:?}", hosts);
                }
                Ok(other) => println!("darwinConfigurations is {}", other.type_name()),
                Err(e) => println!("force darwinConfigurations: {e}"),
            }
        }
    }
}

/// Level 3: navigate to darwinConfigurations.cid
#[test]
fn nix_repo_darwin_cid_exists() {
    if common::skip_if_offline("system_eval_cid") {
        return;
    }
    let dir = nix_repo();
    if !dir.join("flake.nix").exists() {
        return;
    }

    let result = match sui_eval::builtins::evaluate_flake(&dir) {
        Ok(v) => v,
        Err(e) => {
            println!("eval failed: {e}");
            return;
        }
    };

    let path = ["darwinConfigurations", "cid"];
    let mut current = result;
    for key in &path {
        current = match sui_eval::eval::force_value(&current) {
            Ok(v) => v,
            Err(e) => {
                println!("force at {key}: {e}");
                return;
            }
        };
        match current {
            sui_eval::value::Value::Attrs(ref attrs) => {
                current = match attrs.get(*key) {
                    Some(v) => v.clone(),
                    None => {
                        println!("{key} not found");
                        return;
                    }
                };
            }
            _ => {
                println!("expected attrs at {key}, got {}", current.type_name());
                return;
            }
        }
    }

    println!("darwinConfigurations.cid reached successfully");
}

/// Level 4: navigate to config.system.build.toplevel.drvPath
#[test]
fn nix_repo_cid_drv_path() {
    if common::skip_if_offline("system_eval_drv") {
        return;
    }
    let dir = nix_repo();
    if !dir.join("flake.nix").exists() {
        return;
    }

    let result = match sui_eval::builtins::evaluate_flake(&dir) {
        Ok(v) => v,
        Err(e) => {
            println!("eval failed: {e}");
            return;
        }
    };

    let path = [
        "darwinConfigurations",
        "cid",
        "config",
        "system",
        "build",
        "toplevel",
        "drvPath",
    ];
    let mut current = result;
    for key in &path {
        current = match sui_eval::eval::force_value(&current) {
            Ok(v) => v,
            Err(e) => {
                println!("force at {key}: {e}");
                return;
            }
        };
        match current {
            sui_eval::value::Value::Attrs(ref attrs) => {
                current = match attrs.get(*key) {
                    Some(v) => v.clone(),
                    None => {
                        println!("{key} not found in attrs");
                        return;
                    }
                };
            }
            _ => {
                println!("expected attrs at {key}, got {}", current.type_name());
                return;
            }
        }
    }

    let forced = sui_eval::eval::force_value(&current);
    match forced {
        Ok(sui_eval::value::Value::String(ref s)) => {
            println!("drvPath: {}", s.as_str());
            assert!(
                s.as_str().starts_with("/nix/store/"),
                "drvPath should be a store path"
            );
            assert!(s.as_str().ends_with(".drv"), "drvPath should end with .drv");
        }
        Ok(other) => println!("drvPath is {}", other.type_name()),
        Err(e) => println!("force drvPath: {e}"),
    }
}

// ── M2.6 regression — `lib.nixosSystem` full module set ──────────────
//
// Pins the operator-blocking failure documented in
// `docs/M2.6-MODULE-SYSTEM-FIXPOINT.md`.  Original symptom:
// `lib.nixosSystem { modules = []; }` raised `InfiniteRecursion` in the
// `_module.args.pkgs` ↔ `matchedOptions` bootstrap.  CLOSED 2026-07-11
// via TWO byte-verified laziness fixes (roots #1–#3 sealed earlier):
//
//   ROOT #4a (over-force) — `with X; body` eagerly EVALUATED the
//     namespace at `with`-entry (`eval.rs::eval_expr` With arm).  For
//     nixpkgs' `config = mkIf … (with config.services.X; { … })` module
//     shape, demanding the body's WHNF/keys during collection forced
//     `config.services.X` mid-fixpoint → the empty-Promise partial →
//     `concatLists null`.  Fixed by storing the namespace as a lazy
//     thunk (`maybe_thunk`), forced only on a lookup fallthrough.
//     Repro: `builtins.attrNames (with (throw "X"); { a = 1; })`.
//
//   ROOT #4b (dropped full-set leaf) — a depth-≥2 dotted binding whose
//     leaf is a full-set (`options.hardware.alsa = { … }`) followed by a
//     deeper dotted sibling (`options.hardware.alsa.enablePersistence =
//     …`) merged to ONLY the deeper key, because `merge_nested_insert`
//     required BOTH collision sides to be concrete `Value::Attrs` and a
//     full-set leaf is a lazy `Thunk`.  Fixed by forcing the existing
//     thunk to WHNF (fields stay lazy) before the deep merge.
//     Repro: `builtins.attrNames { o.a = { x = 1; }; o.a.y = 2; }.o.a`.
//
// The assertion is now MANDATORY: `config.system.name` must be a real
// string (`"nixos"`), byte-identical to cppnix.

/// M2.6 — `lib.nixosSystem { modules = []; }` must terminate and yield
/// `config.system.name == "nixos"`.  Regression guard for ROOT #4a/#4b.
#[test]
fn nixos_system_empty_modules_terminates() {
    if common::skip_if_offline("m2_6_regression") {
        return;
    }
    // HOME-relative sui input cache (works on both macOS + Linux).
    let home = std::env::var("HOME").unwrap_or_default();
    let nixpkgs_owned = std::path::PathBuf::from(home).join(
        ".cache/sui/inputs/github-NixOS-nixpkgs-b77b3de/nixpkgs-b77b3de8775677f84492abe84635f87b0e153f0f",
    );
    let nixpkgs_dir = nixpkgs_owned.as_path();
    if !nixpkgs_dir.exists() {
        println!("skip: pinned nixpkgs source not in sui input cache");
        return;
    }
    let expr = format!(
        "let nixpkgs = builtins.getFlake \"path:{}\"; \
         in (nixpkgs.lib.nixosSystem {{ system = \"x86_64-linux\"; modules = []; }}) \
            .config.system.name",
        nixpkgs_dir.display(),
    );
    let result = sui_eval::eval(&expr);
    let value = result.expect("nixosSystem must evaluate without InfiniteRecursion");
    let forced = sui_eval::eval::force_value(&value)
        .expect("system.name forces to a concrete value");
    match forced {
        sui_eval::value::Value::String(s) => {
            assert!(!s.as_str().is_empty(), "system.name must not be empty");
            println!("nixosSystem returned system.name = {:?}", s.as_str());
        }
        other => panic!("expected system.name string, got {}", other.type_name()),
    }
}

/// Regression guard for the cross-file SYMBOL-INTERNING COLLISION (the
/// `parse.nix` `cannot select from null` / `undefined variable: 'attrValues'`
/// bug): a thunk defined in an imported file, forced *after* `eval_with_file`
/// restored the top-level `source_id`, must key its idents' `(source_id,
/// offset)` symbol cache against the file the thunk was DEFINED in — not the
/// ambient source at force time. Fixed by the source-id guard on `Thunk::force`
/// (mirroring the eval-file guard). `lib.systems.elaborate` exercises exactly
/// this cross-file lazy force; before the fix it raised `undefined variable`.
/// Byte-identical to cppnix (`nix eval` gives the same string).
#[test]
fn systems_elaborate_cross_file_intern_parity() {
    if common::skip_if_offline("cross_file_intern") {
        return;
    }
    let home = std::env::var("HOME").unwrap_or_default();
    let nixpkgs_dir = std::path::PathBuf::from(home).join(
        ".cache/sui/inputs/github-NixOS-nixpkgs-b77b3de/nixpkgs-b77b3de8775677f84492abe84635f87b0e153f0f",
    );
    if !nixpkgs_dir.exists() {
        println!("skip: pinned nixpkgs source not in sui input cache");
        return;
    }
    let expr = format!(
        "((import {}/lib).systems.elaborate \"x86_64-linux\").config",
        nixpkgs_dir.display(),
    );
    let value = sui_eval::eval(&expr)
        .expect("elaborate must evaluate (no cross-file intern collision)");
    let forced = sui_eval::eval::force_value(&value).expect("config forces");
    match forced {
        sui_eval::value::Value::String(s) => assert_eq!(
            s.as_str(),
            "x86_64-unknown-linux-gnu",
            "elaborate .config must be byte-identical to cppnix",
        ),
        other => panic!("expected config string, got {}", other.type_name()),
    }
}

// ── Marquee darwin proof — flake-input `outPath` store-materialization ─
//
// The darwin counterpart of the M2.6 nixosSystem proof surfaced its OWN
// frontier, one layer below the module fixpoint (which byte-matches cppnix
// for darwinSystem exactly as it does for nixosSystem — verified via
// `config.system.build.toplevel.name` == "darwin-system-25.11.dirty" and
// `config.system.stateVersion` == 5).
//
// ROOT: a fetched (github/tarball) flake input's `outPath` was the raw
//   sui fetcher CACHE path (`~/.cache/sui/inputs/…`) instead of the cppnix
//   `/nix/store/<narhash>-source` store copy that `self` already produced
//   (`flake_eval.rs` §4c `nar_hash_source_tree`).  Any system config that
//   embeds `nixpkgs.source` into a derivation (nix-darwin's
//   `/etc/nix/registry.json`, NIX_PATH) therefore diverged at the toplevel
//   drvPath while the whole module fixpoint matched byte-for-byte.
//   `parity-bisect` on the darwin toplevel named the exact leaf
//   (`etc-registry.json.drv`) with two symptoms: the embedded `to.path`
//   text differed, and `inputSrcs` was missing the `source` reference.
//
// FIX (`flake_eval.rs`): NAR-hash every fetched input tree to its cppnix
//   `-source` store path (mirroring `self`) AND carry copy-to-store string
//   context on the resulting `outPath` so the downstream derivation records
//   the matching `source` inputSrc.
//
// This assertion pins the root: a transitive flake input's `outPath` MUST
// be an in-store `/nix/store/…-source` path, never a `.cache/sui/inputs`
// path.  Uses the HOME-relative nix-darwin input already in the sui cache.

/// Marquee darwin — a fetched flake input's `outPath` is the in-store
/// `-source` copy, never the raw sui fetcher cache path.
#[test]
fn flake_input_outpath_is_store_source_not_cache() {
    if common::skip_if_offline("marquee_darwin_flake_input_outpath") {
        return;
    }
    let home = std::env::var("HOME").unwrap_or_default();
    // The nix-darwin flake pulled into the sui input cache (HOME-relative).
    let darwin_flake = std::path::PathBuf::from(&home).join(
        ".cache/sui/inputs/github-LnL7-nix-darwin-ebec37af18215214173c98cf6356d0aca24a2585/\
         nix-darwin-ebec37af18215214173c98cf6356d0aca24a2585",
    );
    if !darwin_flake.join("flake.nix").exists() {
        println!("skip: pinned nix-darwin flake not in sui input cache");
        return;
    }
    let expr = format!(
        "builtins.toString (builtins.getFlake \"path:{}\").inputs.nixpkgs.outPath",
        darwin_flake.display(),
    );
    let value = sui_eval::eval(&expr).expect("getFlake input outPath must evaluate");
    let forced = sui_eval::eval::force_value(&value).expect("outPath forces");
    match forced {
        sui_eval::value::Value::String(s) => {
            let p = s.as_str();
            println!("flake input nixpkgs.outPath = {p:?}");
            assert!(
                p.starts_with("/nix/store/") && p.ends_with("-source"),
                "flake input outPath must be an in-store `-source` copy, got {p:?}"
            );
            assert!(
                !p.contains(".cache/sui/inputs"),
                "flake input outPath must NOT leak the sui fetcher cache path, got {p:?}"
            );
        }
        other => panic!("expected outPath string, got {}", other.type_name()),
    }
}