tests/rayon_free_law.rs
//! Guard test for the constellation's **rayon-free law** and the **one-engine
//! law**, now scoped to the ENTIRE workspace (root crate + every member).
//!
//! Rule zero (`.nornir/design.md`, `.nornir/gatling-guide.md`): the constellation
//! carries no rayon, and there is exactly ONE parallel engine — the leaf
//! `gatling` crate (`gatling` / `gatling_forkjoin` streaming + fork-join pools,
//! built on `std::thread::scope` + an atomic cursor). No codec may hand-roll a
//! private work-stealing pool; every decode fan-out routes through
//! `gatling::gatling_forkjoin::gatling_for_each` (or the streaming `gatling::run`).
//!
//! The `fix/gatling` port made this true across the whole tree: the engine moved
//! into its own leaf crate (so the codecs can depend on it without a cycle), and
//! the last private pools were deleted —
//! - `lgz::par_map_indexed` (scoped-thread map) → gatling_for_each
//! - `lbzip2::par::par_map` (hand-rolled work-steal map) → gatling_for_each
//! - `ljar` / `lzip-parallel` `rayon::ThreadPool` + `par_iter` → gatling_for_each
//! and the root `rayon` dep plus the two codec `rayon` deps were dropped.
//!
//! This test mechanically re-checks both claims so a future edit that reaches
//! for rayon OR stands up a private thread pool trips a red test instead of
//! silently falsifying the documented laws. The old `ljar` / `lzip-parallel`
//! carve-out is GONE — those crates are now held to the same law as the rest.
//!
//! Reinvented pools are banned in three flavours: rayon adaptors/deps
//! ([`FORBIDDEN_RAYON`]), detached/work-stealing pools (`thread::spawn`,
//! `thread::Builder`, `crossbeam`, `ThreadPoolBuilder` — [`FORBIDDEN_PRIVATE_POOL`]), and — new
//! here — scoped `std::thread::scope` worker pools ([`FORBIDDEN_SCOPED_POOL`]).
//! `thread::scope` is gatling's own primitive, so it is legal in the engine
//! crate and in a short, enumerated allowlist ([`SCOPED_POOL_ALLOW`]) of
//! pre-gatling algorithms (psort / xml / vtd); a NEW file that hand-rolls one
//! instead of calling `gatling_for_each` trips the guard. As of 2026-07-22 the
//! whole of osm-katana and both static-search-tree builds are OFF that
//! allowlist — the only scope pools left outside the engine are the root
//! crate's sample sort and its VTD/XML scanners.
//!
//! # What the pool laws govern: SHIPPED code, not test code
//!
//! 2026-08-04. The private-pool and scoped-pool checks skip `#[cfg(test)]`-gated
//! regions ([`cfg_test_mask`]). The rayon check does **not** — see below for why
//! the exemption is asymmetric.
//!
//! This is a narrowing, and it is argued rather than assumed. It was forced by
//! `lbzip2/src/limits.rs`, whose `OutputBudget` unit test drives 16 raw
//! `std::thread::spawn` threads at one shared atomic to prove its `saturating_sub`
//! cannot wrap the ceiling back up into a floor. Four reasons that is not the sin
//! this law names:
//!
//! 1. **The rule already does not govern test code — only by accident of file
//! placement.** [`workspace_src_roots`] scans `<crate>/src/**` and nothing
//! else, so `osm-katana/tests/convert_cancel.rs` and
//! `osm-katana/benches/pbf_pass2_plan.rs` each hold a bare `thread::spawn`
//! today and this guard is green over both. Lifting the identical probe out of
//! `lbzip2/src/limits.rs` into `lbzip2/tests/` would satisfy the guard while
//! changing nothing about the risk. A rule that a `git mv` satisfies is
//! measuring location, not policy.
//! 2. **`#[cfg(test)]` code is not in the artifact.** It is compiled out of every
//! release build and is unreachable from any decode path. The law's subject —
//! "no codec may hand-roll a private work-stealing pool" — is about what the
//! shipped codec does with cores, and a `cfg(test)` block does nothing with
//! them outside `cargo test`.
//! 3. **Routing THIS probe through the engine would make it blind.**
//! `gatling_for_each` resolves workers as `min(requested, units)` and returns
//! `(0..n).map(f).collect()` when that is 1 (`gatling_forkjoin.rs:76-78`), so
//! on a single-core runner the "concurrent overshoot" probe would execute
//! strictly sequentially and still report green — LAW 2's identity-value trap,
//! installed deliberately. And `gatling_for_each` hands each worker a
//! *disjoint* index off an atomic cursor precisely so they do not contend;
//! using it to manufacture contention is the tool backwards.
//! 4. **It would be circular.** `OutputBudget` is the counter the gatling workers
//! themselves drain (`lbzip2/src/parallel.rs`). Testing a synchronisation
//! primitive through the pool that consumes it means an engine bug and a
//! primitive bug can cancel out.
//!
//! ## Why the exemption is asymmetric
//!
//! [`FORBIDDEN_RAYON`] keeps applying inside `#[cfg(test)]`, with no exemption at
//! all. That is deliberate: rayon does not creep in as a stray `thread::spawn`,
//! it creeps in as a **manifest edit**, and a `[dev-dependencies] rayon` is one
//! character (`dev-`) away from being a real one. The primitive that a test may
//! legitimately reach for is a raw std thread; it is never rayon. So the raw
//! primitives get the `cfg(test)` carve-out and the rayon tokens do not.
#[path = "law_common/mod.rs"]
mod law_common;
use std::path::{Path, PathBuf};
/// A byte-for-byte copy of `text` with every **comment body** and every **string
/// / char literal body** replaced by spaces, newlines preserved.
///
/// One code-only view of a file, computed once and used for BOTH the token scan
/// and [`cfg_test_mask`] (LAW 5 — one writer, not two views that can disagree).
/// It replaces the old per-line `strip_line_comment`, which had two holes: it
/// truncated at the first `//` even inside a string (`let u = "http://x"; …`
/// hid everything after it — a fail-*open* miss), and it did not know about
/// `/* … */` at all.
///
/// Brace-accurate is the load-bearing part for the mask: a Rust source line may
/// hold an *unbalanced* brace inside a literal — `write!(f, "{{")` is exactly
/// that, and osm-katana's JSON emitters are full of them — and a miscounted
/// depth would drag the `cfg(test)` exemption over live code.
fn blank_noncode(text: &str) -> String {
let b = text.as_bytes();
let mut out = vec![b' '; b.len()];
let mut i = 0usize;
// `true` when the previous byte could end an identifier, which is how a
// string prefix (`r"…"`, `b"…"`, `br#"…"#`) is told from an identifier that
// merely ends in `r` or `b` (`for r in …`, `let br = …`).
let ident_byte = |c: u8| c.is_ascii_alphanumeric() || c == b'_';
while i < b.len() {
let c = b[i];
if c == b'\n' {
out[i] = b'\n';
i += 1;
continue;
}
// Line comment: blank to end of line.
if c == b'/' && i + 1 < b.len() && b[i + 1] == b'/' {
while i < b.len() && b[i] != b'\n' {
i += 1;
}
continue;
}
// Block comment, nesting as Rust's do.
if c == b'/' && i + 1 < b.len() && b[i + 1] == b'*' {
let mut depth = 1usize;
i += 2;
while i < b.len() && depth > 0 {
if b[i] == b'\n' {
out[i] = b'\n';
i += 1;
} else if b[i] == b'/' && i + 1 < b.len() && b[i + 1] == b'*' {
depth += 1;
i += 2;
} else if b[i] == b'*' && i + 1 < b.len() && b[i + 1] == b'/' {
depth -= 1;
i += 2;
} else {
i += 1;
}
}
continue;
}
// Raw string, with or without a `b` prefix: r"…", r#"…"#, br##"…"##.
let prefix_ok = i == 0 || !ident_byte(b[i - 1]);
if prefix_ok && (c == b'r' || (c == b'b' && i + 1 < b.len() && b[i + 1] == b'r')) {
let mut j = i + if c == b'b' { 2 } else { 1 };
let hash_start = j;
while j < b.len() && b[j] == b'#' {
j += 1;
}
let hashes = j - hash_start;
if j < b.len() && b[j] == b'"' {
j += 1;
// Closing is `"` followed by exactly `hashes` `#`.
loop {
if j >= b.len() {
break;
}
if b[j] == b'\n' {
out[j] = b'\n';
j += 1;
continue;
}
if b[j] == b'"' {
let mut k = j + 1;
let mut seen = 0usize;
while k < b.len() && b[k] == b'#' && seen < hashes {
k += 1;
seen += 1;
}
if seen == hashes {
j = k;
break;
}
}
j += 1;
}
i = j;
continue;
}
// Not a raw string after all — fall through as ordinary code.
}
// Ordinary string, with or without a `b` prefix.
if c == b'"' || (c == b'b' && prefix_ok && i + 1 < b.len() && b[i + 1] == b'"') {
let mut j = i + if c == b'b' { 2 } else { 1 };
while j < b.len() {
if b[j] == b'\\' {
j += 2;
continue;
}
if b[j] == b'"' {
j += 1;
break;
}
if b[j] == b'\n' {
out[j] = b'\n';
}
j += 1;
}
i = j;
continue;
}
// Char literal — but NOT a lifetime (`&'a str`, `'static`). A char
// literal is `'\<esc>…'` or a single char then a closing quote; anything
// else is a lifetime and is ordinary code.
if c == b'\'' {
let escaped = i + 1 < b.len() && b[i + 1] == b'\\';
let single = i + 2 < b.len() && b[i + 2] == b'\'';
if escaped || single {
let mut j = i + 1;
while j < b.len() {
if b[j] == b'\\' {
j += 2;
continue;
}
if b[j] == b'\'' {
j += 1;
break;
}
j += 1;
}
i = j;
continue;
}
}
out[i] = c;
i += 1;
}
// Every byte written is either the original ASCII byte, a space, or a
// newline; multi-byte UTF-8 bodies only ever live inside literals/comments,
// which are blanked, so the result is valid UTF-8 by construction.
String::from_utf8(out).expect("blanked source stays valid UTF-8")
}
/// Is this `#[cfg(...)]` attribute gated on the **test** cfg?
///
/// Matches `#[cfg(test)]` and `#[cfg(all(test, …))]` — the only two forms in the
/// tree — by looking for a bare `test` token in the predicate. `#[cfg(not(test))]`
/// is explicitly REFUSED: that marks non-test code and must stay governed.
/// `feature = "testmatrix"` tokenises to `testmatrix`, not `test`, so it does not
/// match.
fn is_cfg_test_attr(code: &str) -> bool {
let Some(open) = code.find("#[cfg(") else {
return false;
};
let pred = &code[open + "#[cfg(".len()..];
if pred.contains("not(test") {
return false;
}
pred.split(|c: char| !(c.is_ascii_alphanumeric() || c == '_'))
.any(|t| t == "test")
}
/// Per-line mask over `text`: `true` where the line lies inside a
/// `#[cfg(test)]`-gated item.
///
/// Brace-counted over [`blank_noncode`], so literals and comments cannot move the
/// depth. An attribute that turns out to gate a *non-block* item (`#[cfg(test)]
/// use foo::Bar;` — a `;` arrives at the attribute's own depth before any `{`)
/// exempts only that item, never the block that happens to follow it.
fn cfg_test_mask(text: &str) -> Vec<bool> {
let code = blank_noncode(text);
let mut mask = vec![false; text.lines().count()];
let mut line = 0usize;
let mut depth: i32 = 0;
// Depth at which a `#[cfg(test)]` attribute was seen, awaiting its item.
let mut pending: Option<i32> = None;
// Depth to return to before the exempt region ends.
let mut inside: Option<i32> = None;
for (raw_line, code_line) in text.lines().zip(code.lines()) {
let _ = raw_line;
if inside.is_some() || pending.is_some() {
if line < mask.len() {
mask[line] = true;
}
}
if inside.is_none() && pending.is_none() && is_cfg_test_attr(code_line) {
pending = Some(depth);
if line < mask.len() {
mask[line] = true;
}
}
for ch in code_line.chars() {
match ch {
'{' => {
depth += 1;
if let Some(at) = pending.take() {
inside = Some(at);
}
}
'}' => {
depth -= 1;
if let Some(at) = inside {
if depth <= at {
inside = None;
}
}
}
';' => {
// A non-block item closed the attribute at its own depth.
if let Some(at) = pending {
if depth == at {
pending = None;
}
}
}
_ => {}
}
}
line += 1;
}
mask
}
/// Recursively collect every `*.rs` path under `dir`.
fn rs_files(dir: &Path, out: &mut Vec<PathBuf>) {
let Ok(rd) = std::fs::read_dir(dir) else {
return;
};
for entry in rd.flatten() {
let path = entry.path();
if path.is_dir() {
rs_files(&path, out);
} else if path.extension().and_then(|e| e.to_str()) == Some("rs") {
out.push(path);
}
}
}
/// The workspace root (this crate's manifest dir) and every member's `src/` tree.
///
/// Members come from [`law_common::workspace_src_roots`] — ONE reader, shared with
/// `bench_target_law.rs` and `required_features_law.rs`. It used to be a private copy
/// that read `members = [...]` off a SINGLE line; see that module for why that made
/// this law silently narrow to the root crate the moment the array wrapped.
fn workspace_src_roots() -> Vec<PathBuf> {
law_common::workspace_src_roots()
}
/// Tokens that can only appear when **rayon** is actually being *used*. Forbidden
/// in EVERY crate, no exceptions — the whole tree is rayon-free.
const FORBIDDEN_RAYON: &[&str] = &[
"use rayon",
"rayon::",
"extern crate rayon",
// Rayon parallel-iterator adaptors, matched as *method calls* (`.par_iter(`)
// so a plain identifier like `par_sorted` in unrelated code is not a false
// positive — only an actual rayon call trips the law.
".into_par_iter(",
".par_iter(",
".par_iter_mut(",
".par_bridge(",
".par_chunks(",
".par_sort(",
".par_sort_by(",
".par_sort_unstable(",
"ParallelIterator",
"IntoParallelIterator",
];
/// Tokens that stand up a **private worker pool** — the sin the one-engine law
/// forbids anywhere but the sanctioned leaf `gatling` crate. `thread::spawn`
/// (a detached compute thread), `crossbeam` (scoped/work-steal helpers), and
/// rayon's own pool builders. `thread::scope` is a reinvented pool too, but it
/// is the gatling engine's *own* primitive and predates the port in a handful of
/// root/osm-katana algorithms, so it gets its own check with a documented
/// one-engine-guard allowlist ([`FORBIDDEN_SCOPED_POOL`] /
/// [`SCOPED_POOL_ALLOW`]) rather than living here.
const FORBIDDEN_PRIVATE_POOL: &[&str] = &[
"thread::spawn",
// A `std::thread::Builder` (`thread::Builder::new()…spawn()`) is the exact same
// detached OS thread as `thread::spawn`, just with a name/stack-size — a
// Builder-based worker pool would otherwise evade the `thread::spawn` token
// entirely. Matched on the fully-qualified `thread::Builder` segment (NOT a bare
// `Builder::new`, which the Arrow codecs use for hundreds of column builders).
"thread::Builder",
"crossbeam",
"rayon::ThreadPool",
"ThreadPoolBuilder",
];
/// A **scoped** worker pool built straight on `std::thread::scope`. This IS the
/// gatling engine's own primitive, so it is legal inside the engine crate; the
/// one-engine law forbids reinventing it anywhere else. A short, explicit
/// allowlist ([`SCOPED_POOL_ALLOW`]) grandfathers the pre-gatling algorithms
/// that still hand-roll it — so a NEW file reaching for `thread::scope` to fan
/// out work (instead of routing through `gatling_for_each`) trips a red test.
const FORBIDDEN_SCOPED_POOL: &[&str] = &["thread::scope"];
/// Documented, path-scoped one-engine guards: the pre-gatling parallel
/// algorithms that still fan out on their own `std::thread::scope` rather than
/// `gatling::gatling_forkjoin::gatling_for_each`. These predate the engine
/// extraction and are the SAME std primitive gatling is built on (a scoped span
/// of workers, not a rayon-style global/work-stealing pool); each is a
/// deliberate, enumerated exception, NOT a blanket crate carve-out — a new
/// scope-pool in any unlisted file trips the law.
/// root crate — sample sort + VTD/XML scanners:
/// `/src/psort.rs`, `/src/xml.rs`, `/src/vtd.rs`
///
/// 2026-07-22: **osm-katana is now empty of scope pools** — `par.rs`,
/// `optimize.rs`, `writer.rs`, `verify.rs`, `side_outputs/search.rs`,
/// `geo2arrow.rs` and `node_store.rs` all came off this list, so a scope pool
/// anywhere in that crate now trips the law with no exception to hide behind.
/// The two static-search-tree builds (`stree.rs`/`stree32.rs`) came off in the
/// same pass — their per-layer block fill is `gatling_scanlines` now. What is
/// left is the root crate's sample sort and the VTD/XML scanners. The list only
/// ever shrinks.
const SCOPED_POOL_ALLOW: &[&str] = &["/src/psort.rs", "/src/xml.rs", "/src/vtd.rs"];
/// The one crate allowed to build worker pools: it IS the engine.
const ENGINE_CRATE_DIR: &str = "/gatling/src/";
/// Documented, path-scoped exemptions to the private-pool ban for legitimately
/// non-pool uses of `std::thread::spawn` / `std::thread::Builder`: single
/// long-lived **streaming / I/O / telemetry** threads (one reader, one
/// writer-sink, one collector draining an mpsc channel, one progress sampler),
/// NOT work-stealing decode pools. These predate the gatling port and model the
/// same reader→sink shape the engine itself uses; forcing a serial sink onto
/// `gatling_for_each` would be nonsense. The old blanket `/bin/` carve-out is
/// GONE — the lbunzip2/lgz/lzip decode bins route through
/// `gatling::ordered::run_ordered_sink` and hold no private thread; a bin that
/// stands one up again trips the law.
/// - osm-katana xml_to_pbf : ONE named blob-writer sink thread draining an
/// mpsc channel (serial output stream, not fan-out).
/// - osm-katana phase_log : one long-lived, named `phase-{name}` progress
/// sampler thread per phase (a telemetry loop that
/// emits a JSON line every interval until its stop
/// flag fires — NOT an N-worker pool).
const PRIVATE_POOL_ALLOW: &[&str] = &[
"/osm-katana/src/xml_to_pbf.rs",
"/osm-katana/src/phase_log.rs",
];
fn norm(path: &Path) -> String {
// Forward-slash form so the substring checks are OS-agnostic.
path.to_string_lossy().replace('\\', "/")
}
/// The ONE token scan all three laws run — over [`blank_noncode`], optionally
/// skipping `#[cfg(test)]` regions. Returns `(1-based line, token, code line)`.
///
/// Extracted so the red probes below drive the *same* code the real scans do
/// (LAW 5): a probe against a reimplementation proves nothing about the guard.
fn scan_text<'t>(
text: &str,
tokens: &[&'t str],
skip_test_gated: bool,
) -> Vec<(usize, &'t str, String)> {
let test_gated = if skip_test_gated {
cfg_test_mask(text)
} else {
vec![false; text.lines().count()]
};
let mut hits = Vec::new();
for (i, code) in blank_noncode(text).lines().enumerate() {
if test_gated[i] {
continue;
}
for tok in tokens {
if code.contains(tok) {
hits.push((i + 1, *tok, code.trim().to_string()));
}
}
}
hits
}
#[test]
fn whole_workspace_is_rayon_free() {
let mut files = Vec::new();
for root in workspace_src_roots() {
rs_files(&root, &mut files);
}
assert!(
!files.is_empty(),
"expected to find .rs files across the workspace"
);
let mut violations = Vec::new();
for file in &files {
let text = std::fs::read_to_string(file).unwrap_or_else(|e| panic!("read {file:?}: {e}"));
// `skip_test_gated = false`, and that is the point: rayon is banned in
// test code too (see the module docs — it arrives via the manifest, and a
// dev-dependency is one edit from a real one).
for (lineno, tok, code) in scan_text(&text, FORBIDDEN_RAYON, false) {
violations.push(format!("{}:{lineno}: live `{tok}` — {code}", norm(file)));
}
}
assert!(
violations.is_empty(),
"rayon-free law violated (rayon must not appear anywhere in the workspace):\n{}",
violations.join("\n"),
);
}
#[test]
fn only_the_gatling_leaf_crate_owns_a_worker_pool() {
let mut files = Vec::new();
for root in workspace_src_roots() {
rs_files(&root, &mut files);
}
assert!(
!files.is_empty(),
"expected to find .rs files across the workspace"
);
let mut violations = Vec::new();
for file in &files {
let p = norm(file);
// The engine crate is the one sanctioned home for worker-pool primitives.
if p.contains(ENGINE_CRATE_DIR) {
continue;
}
let allowed = PRIVATE_POOL_ALLOW.iter().any(|a| p.contains(a));
let text = std::fs::read_to_string(file).unwrap_or_else(|e| panic!("read {file:?}: {e}"));
// `skip_test_gated = true`: `#[cfg(test)]` regions are test code,
// governed exactly like the `tests/` and `benches/` trees this scan has
// never covered. Argued at length in the module docs.
for (lineno, tok, code) in scan_text(&text, FORBIDDEN_PRIVATE_POOL, true) {
// `thread::spawn` / `thread::Builder` are exempt in the documented
// streaming/IO/telemetry sites (single long-lived I/O or sampler
// threads); the pool-builder / crossbeam tokens are never allowed
// outside the engine.
if allowed && (tok == "thread::spawn" || tok == "thread::Builder") {
continue;
}
violations.push(format!("{p}:{lineno}: private pool `{tok}` — {code}"));
}
}
assert!(
violations.is_empty(),
"one-engine law violated (only the leaf `gatling` crate may build a worker pool; \
route decode fan-out through `gatling::gatling_forkjoin::gatling_for_each`):\n{}",
violations.join("\n"),
);
}
#[test]
fn no_reinvented_scoped_pool_outside_gatling() {
let mut files = Vec::new();
for root in workspace_src_roots() {
rs_files(&root, &mut files);
}
assert!(
!files.is_empty(),
"expected to find .rs files across the workspace"
);
let mut violations = Vec::new();
for file in &files {
let p = norm(file);
// The engine crate owns `thread::scope` — it IS the one sanctioned pool.
if p.contains(ENGINE_CRATE_DIR) {
continue;
}
// Explicitly grandfathered pre-gatling algorithms.
if SCOPED_POOL_ALLOW.iter().any(|a| p.contains(a)) {
continue;
}
let text = std::fs::read_to_string(file).unwrap_or_else(|e| panic!("read {file:?}: {e}"));
// Same narrowing as the private-pool check above, for the same reason.
for (lineno, tok, code) in scan_text(&text, FORBIDDEN_SCOPED_POOL, true) {
violations.push(format!(
"{p}:{lineno}: reinvented scoped pool `{tok}` — {code}"
));
}
}
assert!(
violations.is_empty(),
"one-engine law violated (a new file hand-rolls a `std::thread::scope` worker pool \
outside the leaf `gatling` crate; route decode/scan fan-out through \
`gatling::gatling_forkjoin::gatling_for_each`, or — if it is a legitimate pre-gatling \
algorithm — add it to SCOPED_POOL_ALLOW with a rationale):\n{}",
violations.join("\n"),
);
}
/// No manifest in the workspace may declare a `rayon` dependency — the port
/// dropped every one, and a transitive re-add would quietly re-arm the global
/// pool the law forbids. Scans dependency-table lines of the root + every member
/// `Cargo.toml` (comments in a manifest freely discuss rayon).
#[test]
fn no_manifest_declares_rayon() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let mut manifests = vec![root.join("Cargo.toml")];
let root_manifest =
std::fs::read_to_string(root.join("Cargo.toml")).expect("read root Cargo.toml");
// Members come from `law_common::member_names` — the ONE reader shared with
// `workspace_src_roots`. This function used to parse `members = [...]` off a
// SINGLE line, which is a scan that shrinks to just the root manifest the
// moment the array wraps — and a manifest law that scans one manifest still
// passes. The array is one line today; that is a formatting accident, not a
// guarantee, so the parse must not depend on it.
for name in law_common::member_names(&root_manifest) {
manifests.push(root.join(name).join("Cargo.toml"));
}
// The breadth of the scan is itself asserted. Without this, a members parse
// that returns nothing leaves `manifests` holding the root alone, every
// member goes unread, and the law reports a clean green over one file.
assert!(
manifests.len() > 1,
"manifest scan collapsed to {} file(s) — the members parse found no workspace \
members, so every member Cargo.toml went unread and this law would pass \
without looking at them",
manifests.len(),
);
for manifest in &manifests {
assert!(
manifest.is_file(),
"declared workspace member has no Cargo.toml at {} — a law that scans a \
path that does not exist is a law that cannot fail",
manifest.display(),
);
}
let mut offenders = Vec::new();
for manifest in &manifests {
let Ok(text) = std::fs::read_to_string(manifest) else {
continue;
};
let mut in_deps = false;
for raw in text.lines() {
let line = raw.trim();
if line.starts_with('[') {
in_deps = line.contains("dependencies]");
continue;
}
if !in_deps {
continue;
}
// TOML, not Rust: comments are `#`, and a commented-out
// `# rayon = "1"` yields the key `# rayon`, which never matches. No
// comment stripping needed or wanted here.
let key = line.split('=').next().unwrap_or("").trim();
if key == "rayon" {
offenders.push(format!("{}: {}", norm(manifest), line.trim()));
}
}
}
assert!(
offenders.is_empty(),
"a workspace Cargo.toml declares a rayon dependency (law forbids it):\n{}",
offenders.join("\n"),
);
}
// ---------------------------------------------------------------------------
// Red probes for the 2026-08-04 `#[cfg(test)]` narrowing.
//
// LAW 2: a carve-out that has never been seen refuse anything is a hole with a
// comment on it. Every probe below drives the SAME `scan_text` / `cfg_test_mask`
// / `blank_noncode` the four laws above run on the real tree — a probe against a
// reimplementation would prove nothing about the guard.
// ---------------------------------------------------------------------------
/// The complete, enumerated list of files the `#[cfg(test)]` narrowing actually
/// forgives today. Not a policy — a *census*, cross-checked against the tree by
/// [`the_cfg_test_carve_out_is_exactly_one_documented_site`] in both directions,
/// so neither a new inline thread pool nor a stale entry can hide in it.
///
/// - `lbzip2/src/limits.rs` : `concurrent_overshoot_cannot_wrap_the_counter_back_up`
/// drives 16 raw threads at one shared `OutputBudget` to prove the
/// `saturating_sub` never wraps the ceiling into a floor. Argued in the module
/// docs: routing it through `gatling_for_each` would take the `workers == 1`
/// serial path on a one-core runner and go permanently, silently green.
const CFG_TEST_POOL_SITES: &[&str] = &["/lbzip2/src/limits.rs"];
/// The narrowing must not have disarmed the law: a pool in ordinary code is
/// still caught, with `skip_test_gated` ON.
#[test]
fn a_production_pool_is_still_caught_with_the_carve_out_active() {
let src = "fn decode(units: &[u8]) {\n let h = std::thread::spawn(move || work());\n h.join().unwrap();\n}\n";
let hits = scan_text(src, FORBIDDEN_PRIVATE_POOL, true);
assert_eq!(
hits.len(),
1,
"production `thread::spawn` went unseen: {hits:?}"
);
assert_eq!(hits[0].0, 2);
}
/// The carve-out covers the `#[cfg(test)]` block and stops dead at its closing
/// brace. The trailing production spawn is the whole point: an exemption that
/// runs to end-of-file would swallow it and this assert is what proves it does
/// not.
#[test]
fn the_carve_out_stops_at_the_closing_brace() {
let src = r#"
fn shipped_a() {
let _ = std::thread::spawn(|| ());
}
#[cfg(test)]
mod tests {
#[test]
fn probe() {
let h = std::thread::spawn(|| ());
h.join().unwrap();
}
}
fn shipped_b() {
let _ = std::thread::spawn(|| ());
}
"#;
let all = scan_text(src, FORBIDDEN_PRIVATE_POOL, false);
assert_eq!(
all.len(),
3,
"fixture is wrong — expected three spawns, got {all:?}"
);
let live = scan_text(src, FORBIDDEN_PRIVATE_POOL, true);
let lines: Vec<usize> = live.iter().map(|h| h.0).collect();
assert_eq!(
lines,
vec![3, 16],
"carve-out leaked past `mod tests`: {live:?}"
);
}
/// An *unbalanced* brace inside a string literal — `write!(f, "{{")` and the JSON
/// emitters in osm-katana are full of them — must not shift the nesting depth.
/// If it did, the exemption would end early or late and either blind the law or
/// falsely accuse a test.
#[test]
fn an_unbalanced_brace_in_a_literal_cannot_move_the_carve_out() {
let src = r###"
#[cfg(test)]
mod tests {
fn emit(f: &mut String) {
f.push_str("{");
f.push_str("}}}}");
let _ = '}';
let _ = r#"{{{"#;
let _ = std::thread::spawn(|| ());
}
}
fn shipped() {
let _ = std::thread::spawn(|| ());
}
"###;
// First assert the mechanism, so this probe cannot pass for the wrong
// reason: every one of those braces must be gone from the code-only view.
let blanked = blank_noncode(src);
for (i, l) in blanked
.lines()
.enumerate()
.filter(|(i, _)| (5..=8).contains(&(i + 1)))
{
assert!(
!l.contains('{') && !l.contains('}'),
"line {} kept a literal brace in the code view: {l:?}",
i + 1
);
}
let live = scan_text(src, FORBIDDEN_PRIVATE_POOL, true);
let lines: Vec<usize> = live.iter().map(|h| h.0).collect();
assert_eq!(
lines,
vec![14],
"literal braces moved the depth — the exemption landed on the wrong lines: {live:?}"
);
}
/// `#[cfg(not(test))]` marks code that ships *outside* tests. It must stay fully
/// governed; a naive "the attribute mentions `test`" check would exempt it.
#[test]
fn cfg_not_test_is_not_exempt() {
let src = "#[cfg(not(test))]\nfn shipped() {\n let _ = std::thread::spawn(|| ());\n}\n";
assert!(
!is_cfg_test_attr("#[cfg(not(test))]"),
"`not(test)` must not read as test-gated"
);
let live = scan_text(src, FORBIDDEN_PRIVATE_POOL, true);
assert_eq!(
live.len(),
1,
"`#[cfg(not(test))]` code was wrongly forgiven: {live:?}"
);
}
/// A feature named `testmatrix` is not the `test` cfg. This crate really has
/// `#[cfg(feature = "testmatrix")]` in fifteen places, and every one of them
/// ships.
#[test]
fn a_feature_whose_name_starts_with_test_is_not_the_test_cfg() {
assert!(!is_cfg_test_attr(r#"#[cfg(feature = "testmatrix")]"#));
assert!(is_cfg_test_attr("#[cfg(test)]"));
assert!(is_cfg_test_attr(r#"#[cfg(all(test, feature = "gen"))]"#));
}
/// `#[cfg(test)] use …;` gates a single non-block item. The exemption must close
/// on that `;` and not run on into whatever block comes next.
#[test]
fn a_cfg_test_use_does_not_exempt_the_block_after_it() {
let src =
"#[cfg(test)]\nuse std::thread;\n\nfn shipped() {\n let _ = thread::spawn(|| ());\n}\n";
let live = scan_text(src, FORBIDDEN_PRIVATE_POOL, true);
assert_eq!(
live.len(),
1,
"a `#[cfg(test)] use` swallowed the function after it: {live:?}"
);
assert_eq!(live[0].0, 5);
}
/// rayon gets NO carve-out — not even inside `#[cfg(test)]`. This is the
/// asymmetry the module docs argue for, asserted rather than described.
#[test]
fn rayon_is_banned_inside_cfg_test_too() {
let src = "#[cfg(test)]\nmod tests {\n use rayon::prelude::*;\n}\n";
// How the real `whole_workspace_is_rayon_free` calls it: skip_test_gated = false.
let hits = scan_text(src, FORBIDDEN_RAYON, false);
assert!(
!hits.is_empty(),
"rayon inside `#[cfg(test)]` must still trip the law"
);
// And prove the flag is what does it, so this can never pass by accident.
assert!(
scan_text(src, FORBIDDEN_RAYON, true).is_empty(),
"fixture is wrong — with the carve-out on this must be forgiven, which is \
exactly why `whole_workspace_is_rayon_free` never turns it on"
);
}
/// The hole the old per-line `strip_line_comment` left: it truncated at the
/// first `//`, even one inside a string, and everything after it on that line
/// went unscanned. A fail-*open* miss, and this is its red probe.
#[test]
fn a_double_slash_inside_a_string_no_longer_hides_the_rest_of_the_line() {
let src = "fn f() {\n let u = \"https://x\"; let _ = std::thread::spawn(|| ());\n}\n";
let hits = scan_text(src, FORBIDDEN_PRIVATE_POOL, true);
assert_eq!(
hits.len(),
1,
"a `//` inside a string hid a real pool: {hits:?}"
);
}
/// The other direction: a token that only *appears* inside a comment or a string
/// is commentary about the law, not a violation of it.
#[test]
fn a_token_that_only_appears_in_a_comment_or_a_literal_is_not_a_violation() {
let src = "// never call thread::spawn here\n/* thread::spawn */\nfn f() { let s = \"thread::spawn\"; let _ = s; }\n";
let hits = scan_text(src, FORBIDDEN_PRIVATE_POOL, true);
assert!(hits.is_empty(), "commentary read as a violation: {hits:?}");
}
/// The `#[cfg(test)]` carve-out is a census, not a blanket. Recompute it against
/// the real tree and require it to match [`CFG_TEST_POOL_SITES`] **exactly**, in
/// both directions: a new inline pool anywhere in the workspace goes red and has
/// to be argued, and an entry that stops applying goes red and has to be pruned.
#[test]
fn the_cfg_test_carve_out_is_exactly_one_documented_site() {
let mut files = Vec::new();
for root in workspace_src_roots() {
rs_files(&root, &mut files);
}
assert!(
!files.is_empty(),
"expected to find .rs files across the workspace"
);
let pool_tokens: Vec<&str> = FORBIDDEN_PRIVATE_POOL
.iter()
.chain(FORBIDDEN_SCOPED_POOL.iter())
.copied()
.collect();
let mut forgiven = Vec::new();
for file in &files {
let p = norm(file);
if p.contains(ENGINE_CRATE_DIR)
|| PRIVATE_POOL_ALLOW.iter().any(|a| p.contains(a))
|| SCOPED_POOL_ALLOW.iter().any(|a| p.contains(a))
{
continue;
}
let text = std::fs::read_to_string(file).unwrap_or_else(|e| panic!("read {file:?}: {e}"));
let with = scan_text(&text, &pool_tokens, false).len();
let without = scan_text(&text, &pool_tokens, true).len();
if with > without {
forgiven.push(format!("{p} ({} line(s))", with - without));
}
}
for f in &forgiven {
assert!(
CFG_TEST_POOL_SITES.iter().any(|s| f.contains(s)),
"a NEW `#[cfg(test)]` thread pool appeared and is being forgiven silently: {f}\n\
Either route it through gatling, or add it to CFG_TEST_POOL_SITES with the \
argument for why a raw thread is the honest primitive there.",
);
}
for site in CFG_TEST_POOL_SITES {
assert!(
forgiven.iter().any(|f| f.contains(site)),
"stale carve-out: `{site}` no longer holds a `#[cfg(test)]` thread pool. \
A dead entry pre-forgives whatever lands in that file next — delete it.",
);
}
}