The POSIX floor gate inside nix flake check — Floor Shebang · Pack Seat · Check Wire · Graduate Gate
Why the gate is /bin/sh. When a shell gate must graduate to a cargo script.
<!-- hal:authoritative:yaml -->
*Why the gate is /bin/sh. When a shell gate must graduate to a cargo script.*
§I — Frame
Asr session 20. Topic T7 Env & CI. Fifth and final fire of the Nix Rust-roads block (#16 to #20). Home: . Cite: rust-tops scripts/bend-gate.sh + nix/rust-tops-laws.nix + flake checks.law-catalog. Vault mirror: foundry/rust-tops/repo/rust-tops/. Live: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake-check.html.
Session 19 named Schema Read, Shell Seat, and Check Seat. Today the unmarked row asks the floor question under law-catalog: why is the gate a POSIX shell script, what does the laws-pack derivation carry, and when must a shell gate graduate to a cargo script instead of staying on /bin/sh.
Verified on this Mac before drafting:
| Probe | Result |
|---|---|
bend-gate.sh shebang | #!/bin/sh |
NAMES line count / ^law in LAWS.bend | 53 / 53 |
BEND_GATE_NAMES_ONLY=1 ./scripts/bend-gate.sh | bend-gate: 53 laws named · exit 0 |
bend on PATH | absent · soft names-only exit 0 |
checks.aarch64-darwin attrNames | cargo-tops, law-catalog, rust-tops-laws |
Today's Duha Nix packaging shell (lesson_class: duha, patterns crate) packages Beat A. It does not consume this Asr cursor.
Done-criteria from the syllabus: say why the gate is /bin/sh (no rustc on the floor) and when a shell gate must graduate to a cargo script.
Not a remake of session 19 Schema Read. Not Bend regenerate body (s07). Bend Asr spine has no unmarked row after #9.
§II — Floor Shebang (named technique)
Floor Shebang: the gate starts with #!/bin/sh on purpose.
Open scripts/bend-gate.sh. The first line is not bash-for-comfort and not a Rust binary. It is POSIX sh. The script then:
- Resolves repo root and
RUST_TOPS_LAWS(defaultlaws/). - Refuses missing
LAWS.bend/PROOF.bend/NAMES(exit 2). - Counts
NAMESlines vs^lawstatements inLAWS.bend. - For each name, asserts the law line exists in
LAWS.bendand the name appears inPROOF.bend. - If
BEND_GATE_NAMES_ONLY=1, prints the count and exits 0. - If
bendis missing on PATH, soft names-only: print and exit 0. - Else
exec bend PROOF.bend.
Yagyu: Floor Shebang means CI can assert catalog parity with grep and sh, without rustc, without Bend, without compiling gen-laws.rs.
Musashi: the floor answers "are the harvested names stated?" It does not answer "did Bend prove every stated law on this host?"
§III — Pack Seat (named technique)
Pack Seat: nix/rust-tops-laws.nix is the laws tree as a store package, not the gate.
stdenvNoCC.mkDerivation {
pname = "rust-tops-laws";
# ...
src = ../laws;
dontConfigure = true;
dontBuild = true;
installPhase = ''
mkdir -p $out/share/rust-tops/laws
cp -R . $out/share/rust-tops/laws/
'';
}
stdenvNoCC is the tell: no C compiler seat, no Rust seat. The derivation copies the pack. Flake checks.rust-tops-laws is "this package builds." Flake checks.law-catalog is "the gate script passes names-only against ./laws."
Do not confuse Pack Seat with Floor Shebang. One ships files. One asserts name parity inside nix flake check.
§IV — Check Wire (named technique)
Check Wire: how law-catalog pins the floor inside the sandbox.
From flake.nix:
law-catalog = pkgs.runCommand "rust-tops-law-catalog" { } ''
set -eu
export BEND_GATE_NAMES_ONLY=1
export RUST_TOPS_LAWS=${./laws}
bash ${./scripts/bend-gate.sh}
echo ok >"$out"
'';
Read the contracts:
| Wire | Meaning |
|---|---|
BEND_GATE_NAMES_ONLY=1 | sandbox never asks for Bend |
RUST_TOPS_LAWS=${./laws} | gate reads the flake-local laws tree |
bash ${./scripts/bend-gate.sh} | run the script; script itself stays /bin/sh |
no gen-laws.rs | regenerate is host work, not check work |
nix flake check builds every checks attr. If name parity fails, the flake fails. That is the CI noun for Topics #20.
Chozanshi: if the sandbox has no Bend and no rustc for the generator, then names-only sh must still fail closed on a missing law name; thus regen stays a separate host step (Bend s07 Catalog Emit).
§V — Graduate Gate (named technique)
Graduate Gate (T7 floor version): keep shell until the check must compile or interpret Rust.
| Seat | Tool | When it belongs |
|---|---|---|
| Floor gate | /bin/sh + grep (bend-gate.sh) | assert name/statement parity; no deps; CI sandbox |
| Cargo script | gen-laws.rs (cargo +nightly -Zscript) | regenerate the triad on a maintainer host |
| Crate / writer | buildRustPackage / writeRust* | locked deps, store package, or PATH binary |
Graduate the shell gate to a cargo script when parity-by-grep is no longer enough: you need typed parsing, crate deps, or a binary that must exist in $out. Do not graduate just because Rust is nearby. gen-laws.rs already owns regen; bend-gate.sh owns the floor. Session 17 Graduate Gate sorted writer vs script vs crate. Session 20 adds the floor rule: **CI parity stays /bin/sh until the assertion itself needs a Rust program.**
Corpus honesty: rust-tops has not replaced bend-gate.sh with a Rust checker. That absence is truth. Do not invent a store Rust gate from class.
§VI — Why this road
Asr Nix seats T7 so Rust packaging ends the #16–#20 block with a floor you can name: shebang, pack, check wire, graduation. After crate, writers, musl, and flake schema, the last road move is "what runs when nix flake check hits the laws."
Keep the Duha/Asr split clear: Duha Beat B may package today's lesson crate under lesson_class: duha. Asr advances NIX-SYLLABUS under lesson_class: asr and topic: T7.
§VII — Done-criteria check
Say aloud without looking:
- Floor Shebang: gate is
#!/bin/shso CI needs no rustc and no Bend for name parity. - Pack Seat:
rust-tops-laws.nixcopieslaws/withstdenvNoCC; it is not the gate. - Check Wire:
law-catalogforcesBEND_GATE_NAMES_ONLY=1insiderunCommand. - Graduate Gate: leave shell until the assertion itself needs a Rust program; regen stays cargo-script on host.
§VIII — Common mistakes
- Treating today's Duha Nix packaging shell as this Asr Topics #20 ship.
- Claiming
nix flake checkruns fullbend PROOF.bendwhenlaw-catalogis names-only. - Putting
gen-laws.rscompile into the flake check "to be thorough." - Confusing
checks.rust-tops-laws(pack build) withchecks.law-catalog(gate). - Replacing
/bin/shwith a Rust binary from class without a real assertion need. - Inventing a Bend Phase 2 lesson row because the duo peer spine is exhausted.
§IX — Boundaries
- Not session 19 Schema Read / Shell Seat remake as the whole lesson.
- Not session 17 writers body.
- Not Bend Catalog Emit / regenerate (s07) as the Nix seat.
- Not Python
withPackages(retired Asr lane). - Not pushing main or editing rust-tops product files.
- Not authoring Maghrib quiz×4 or VIMP.
§X — Close
Session 19 mapped the flake surface. Session 20 maps Floor Shebang, Pack Seat, Check Wire, and Graduate Gate against bend-gate.sh, rust-tops-laws.nix, and checks.law-catalog. NIX-SYLLABUS Topics #16 to #20 (Rust roads) are now complete; Phase 2 waits on a teammate.
Related:
Name the shebang. Name the names-only export. Leave the keyboard.