Ten of seventeen: every gate verify.sh runs is Rust

decisions, corpus and census joined the six checkers. verify.sh still shells out to Python for three GPU/surface generators; every other stage is obscene-tool. 174 tests.

The two census generators became one module. gen-corpus.py and gen-nids.py read the same data/ and emit the same macro shape, and keeping them apart is how the group-tag collision (libkernel against libKernel) got fixed twice. tool/src/census.rs holds both.

Each generator was verified by regenerating the committed header and diffing:

header differing lines what they were
corpus.h 2 the Generated by attribution
nids.h 4 attribution, and one sentence I rewrote
decision index 2 attribution

Every symbol, identifier, group and tag byte-identical. That is the check worth doing on a generator: not "does it run" but "does it produce the same file", against an output that is committed and therefore diffable.

One thing kept deliberately: thousands separators. The Python rendered 34,958 and the first Rust 34958. Cosmetic, and these headers are committed - a formatting change makes every regeneration a whole-file diff, which buries the one line that actually moved.

run() in main.rs hit the function-length lint for the third time in a session, once per port. Split into run and run_gate rather than shaving a line each time: the gates are also the arms a reader looks for together, since they are what the build has to pass.

Remaining: three generators (gen-surface, gen-gpu-surface, gen_shaders, plus the one-off gen-font), the mining half of mine-nids, and three analysis scripts.