diff --git a/.claude/board/LATEST_STATE.md b/.claude/board/LATEST_STATE.md index 8719bf006..7362ea185 100644 --- a/.claude/board/LATEST_STATE.md +++ b/.claude/board/LATEST_STATE.md @@ -1,3 +1,8 @@ +## 2026-09-05 — PR #1181 MERGED (`80dbcc35`) + jc clippy sweep — INVENTORY DELTA + +- **Merged:** #1181 — `contract::shape_rank` (`ShapeRankPayload`, `RemeasureKey`, `RemeasureLedger`, `RemeasureError::{AlreadySealed, VersionMismatch}`) and `planner::nested_bands` are on `main`. Consumers today: none outside the two crates' own tests — the D-BLW-5 loop that would inject the payload is PAUSED. See `PR_ARC_INVENTORY.md` 2026-09-05 #1181 entry. +- **jc:** `cargo clippy --manifest-path crates/jc/Cargo.toml --all-targets -- -D warnings` is green on `main` for the first time (TD-JC-CLIPPY-RED-ON-BASE-1 RESOLVED); `jc-proof.yml` now runs that command, same arming as sigker. + ## 2026-09-05 — branch (D-NXG-4 → D-BLW-5, producer half): the payload has a producer and a transform — INVENTORY DELTA - ADDED `lance_graph_planner::nested_bands::{Z2_SCALE, quantize_2z}`, `NestedBandsBuilder::calibrate_equal_width` (the D-BLW-5 design's equal-width-in-2z ladder, beside the equal-mass `calibrate`), `NestedBands::shape_rank(observed, V₀) -> ShapeRankPayload` (asserts 16 bands). Five tests, one on a REAL pooled prior (92 speech frames' lag-1 autocorrelation). diff --git a/.claude/board/PR_ARC_INVENTORY.md b/.claude/board/PR_ARC_INVENTORY.md index 989d86337..77459a225 100644 --- a/.claude/board/PR_ARC_INVENTORY.md +++ b/.claude/board/PR_ARC_INVENTORY.md @@ -1,3 +1,11 @@ +## 2026-09-05 — lance-graph PR #1181 (merged `80dbcc35`, branch `claude/pr-294-ragged-path-validation-170zcy`) — NestedBands sealed + the D-BLW-5 `shape × rank` payload + +- **Added:** `lance_graph_planner::nested_bands` (D-NXG-1/5: `NestedBandsBuilder` quantile / equal-width / explicit ladders, `NestedBands` with `rank`, `entropy`, `budget`, `split`/`merge` returning a NEW version, `best_achievable_floor`, `moments`, `sigma_exact`, `shape_rank`); `lance_graph_contract::shape_rank` (D-NXG-4: `ShapeRankPayload{shape:[u64;16], rank:u8, version}`, `RemeasureKey`, `RemeasureLedger` with `AlreadySealed` + `VersionMismatch`); `jc::stats::{fisher_2z, fisher_2z_inv}`. +- **Locked:** the D-BLW-5 payload law in code — the DTO carries `shape₀ × rank₀`, never the raw statistic; sealed once per `(stat_id, arm, cohort, metric, dataset_version)`; a payload whose frozen version differs from the key is refused. Top band is the universe (E-NXG-18); bucket-0 split bound is the column minimum, not 0 (signed columns). +- **Review arc:** CodeRabbit round 1 — six findings, all verified real, fixed in `7d9e03a3` (version guard, negative split, three length asserts, doc/title/plan wording); the seventh (builder panics → `Result`) declined with reason and accepted by the bot. The three tests the guard broke were fixture bugs, aligned not weakened. +- **Deferred:** the D-BLW-5 LOOP (four arms, bloom criterion, supervisor test file) stays PAUSED — only the payload half was relaunched. `out_of_support` bit on the DTO (E-NXG-22) awaits operator ruling. TD-JC-CLIPPY-RED-ON-BASE-1 filed, resolved in the follow-up PR. +- **Confidence:** High on the contract semantics (tests + bot-verified); Medium on `shape_rank` being the right producer shape for the F± arms, which nothing has exercised. + ## 2026-09-05 — lance-graph PR #1177 (merged `eb84b275`, branch `claude/bindspace-soa-wiring-plan-2026-09`) — the BindSpace→MailboxSoA migration, re-derived from the tree - **Added:** `.claude/plans/bindspace-mailbox-soa-wiring-v1.md` (D-BSW-0..4) + its `STATUS_BOARD` section + an `INTEGRATION_PLANS` index entry. DOC/BOARD ONLY — no code, nothing compiled, no `cargo` at any point (V3 worker rule 7). diff --git a/.claude/board/TECH_DEBT.md b/.claude/board/TECH_DEBT.md index ca788504d..6ea8c2619 100644 --- a/.claude/board/TECH_DEBT.md +++ b/.claude/board/TECH_DEBT.md @@ -1,4 +1,4 @@ -## TD-JC-CLIPPY-RED-ON-BASE-1 (2026-09-05) — OPEN +## TD-JC-CLIPPY-RED-ON-BASE-1 (2026-09-05) — RESOLVED 2026-09-05 (lint sweep + `jc-proof.yml` clippy step, operator-directed after #1181) **`crates/jc` does not pass `cargo clippy --manifest-path crates/jc/Cargo.toml --all-targets -- -D warnings`, and did not before this arc.** Measured by stashing the working tree: the same `unusual_byte_groupings` errors reproduce on `origin/main` in `dueker_zoubouloglou.rs`, `ewa_sandwich.rs`, `ewa_sandwich_3d.rs`, `koestenberger.rs`, `lib.rs`, `pearl.rs`, `pflug.rs`, `probe_p1_gamma_phase.rs`, `sigma_codebook_probe.rs`, `weyl.rs` — none touched by the D-NXG-4 arc; `stats.rs` (the file this arc edits) has zero findings. CI runs tests and `fmt --check` on jc (`jc-proof.yml`, `style.yml:226`) but no clippy step, which is how it went unseen. Same shape as `TD-SIGKER-CLIPPY-RED-ON-BASE-1` (resolved 2026-09-04 by fixing + arming the lint in CI); the same two-step fix applies. Not done here: it is not this arc's code and would widen a payload PR into a lint sweep. diff --git a/.github/workflows/jc-proof.yml b/.github/workflows/jc-proof.yml index abb4cc7ba..75db059b0 100644 --- a/.github/workflows/jc-proof.yml +++ b/.github/workflows/jc-proof.yml @@ -38,6 +38,14 @@ jobs: - name: Run JC tests (6 unit tests) run: cargo test --manifest-path crates/jc/Cargo.toml + # jc is workspace-excluded, so the root clippy job never reaches it; it + # went red unnoticed until TD-JC-CLIPPY-RED-ON-BASE-1 (2026-09-05). Same + # arming as sigker in rust-test.yml: fix once, then gate it here. + - name: Lint JC (workspace-excluded, so root clippy never reaches it) + run: | + cargo clippy --manifest-path crates/jc/Cargo.toml \ + --all-targets -- -D warnings + - name: Run prove_it (substrate proof binary) run: | cargo run --manifest-path crates/jc/Cargo.toml --release --example prove_it diff --git a/crates/jc/examples/l9_loci_real_text.rs b/crates/jc/examples/l9_loci_real_text.rs index 5cf796e0e..d8a6d6730 100644 --- a/crates/jc/examples/l9_loci_real_text.rs +++ b/crates/jc/examples/l9_loci_real_text.rs @@ -25,7 +25,7 @@ //! //! - `ante` — pronoun → antecedent (pronoun events only; gold-labeled) //! - `kausal` — effect-clause event → the cause clause across a causal -//! connective (because/so; gold from the text's connectives) +//! connective (because/so; gold from the text's connectives) //! - `noun-gnd` — nearest nominal grounding (S/O-meaning on this substrate) //! - `verb-gnd` — nearest verbal grounding (P-meaning) //! - `temporal` — nearest temporal marker (closed class: then/when/day/…) @@ -60,6 +60,7 @@ //! 1. WELL-POSED: every jc measure returns `Some`. //! 2. `ante` accuracy ≥ 0.60 AND ≥ the agreement-blind baseline. //! 3. `kausal` hit rate ≥ 0.50. +//! //! KILL: any gate fails (recorded loudly). Agreement magnitudes are not //! gated — their direction is measured, not assumed. //! @@ -575,7 +576,8 @@ fn main() { // ── RELIABILITY: Method A vs Method B on the always-computable loci ──── let content_idx: Vec = (0..toks.len()).filter(|&i| is_content(&toks[i])).collect(); - let dims: [(&str, Box Option>); 5] = [ + type LocusFn<'a> = Box Option + 'a>; + let dims: [(&str, LocusFn); 5] = [ ( "noun-gnd", Box::new(|i, sem| { diff --git a/crates/jc/examples/partof_isa_vs_palette256.rs b/crates/jc/examples/partof_isa_vs_palette256.rs index 46b62f485..bd78b2ba5 100644 --- a/crates/jc/examples/partof_isa_vs_palette256.rs +++ b/crates/jc/examples/partof_isa_vs_palette256.rs @@ -56,6 +56,7 @@ //! under is_a (separation ≥ 0.20 on the [0,1] closeness scale). //! 3. The two readings are NOT redundant: cross-reading Spearman |ρ| < 0.70 //! (if they agreed strongly, one would be redundant — they do not). +//! //! KILL: any gate fails (recorded). Agreement magnitude is reported, its //! direction measured not assumed. //! diff --git a/crates/jc/examples/splat_jaccard_adamic_adar.rs b/crates/jc/examples/splat_jaccard_adamic_adar.rs index 1f4aaf571..6eba2f403 100644 --- a/crates/jc/examples/splat_jaccard_adamic_adar.rs +++ b/crates/jc/examples/splat_jaccard_adamic_adar.rs @@ -21,11 +21,11 @@ //! ## What this probe proves //! //! 1. **Jaccard reduces to L2 popcount-AND / popcount-OR:** -//! J(u, v) = |N(u) ∩ N(v)| / |N(u) ∪ N(v)| -//! = popcount(plane[u] AND plane[v]) / popcount(plane[u] OR plane[v]) +//! `J(u, v) = |N(u) ∩ N(v)| / |N(u) ∪ N(v)| +//! = popcount(plane[u] AND plane[v]) / popcount(plane[u] OR plane[v])` //! 2. **Adamic-Adar reduces to L2 AND-iter + L1 popcount:** -//! AA(u, v) = Σ_{w ∈ N(u) ∩ N(v)} 1 / log(|N(w)|) -//! = sum over set bits of (plane[u] AND plane[v]) of 1/log(degree[w]) +//! `AA(u, v) = Σ_{w ∈ N(u) ∩ N(v)} 1 / log(|N(w)|) +//! = sum over set bits of (plane[u] AND plane[v]) of 1/log(degree[w])` //! 3. **Same-community pairs score measurably higher** on both metrics //! than cross-community pairs (the "found edges" signal). //! 4. **Mutate-back is one-pass:** for top-K most-similar pairs, deposit @@ -70,6 +70,7 @@ fn or_popcount(a: &AwarenessPlane16K, b: &AwarenessPlane16K) -> u32 { acc } +#[allow(dead_code)] // documented L2 AND-iter shape; kept beside the popcount path it explains fn iter_set_bits(p: &AwarenessPlane16K, mut f: impl FnMut(u32)) { for (word_idx, &word) in p.0.iter().enumerate() { let mut w = word; @@ -92,7 +93,9 @@ fn splitmix64(state: &mut u64) -> u64 { // ── planted graph (same template as LPA + Louvain probes) ────────────────── struct PlantedGraph { + #[allow(dead_code)] // planted-graph descriptor; read by the sibling probes n: u32, + #[allow(dead_code)] k_communities: u32, ground_truth: Vec, planes: Vec, diff --git a/crates/jc/examples/splat_louvain_modularity.rs b/crates/jc/examples/splat_louvain_modularity.rs index ac21742fc..e832979aa 100644 --- a/crates/jc/examples/splat_louvain_modularity.rs +++ b/crates/jc/examples/splat_louvain_modularity.rs @@ -97,6 +97,7 @@ fn splitmix64(state: &mut u64) -> u64 { struct PlantedGraph { n: u32, + #[allow(dead_code)] // planted-graph descriptor; read by the sibling probes k_communities: u32, ground_truth: Vec, planes: Vec, diff --git a/crates/jc/examples/splat_lpa_label_propagation.rs b/crates/jc/examples/splat_lpa_label_propagation.rs index b3a9669ee..71df9f416 100644 --- a/crates/jc/examples/splat_lpa_label_propagation.rs +++ b/crates/jc/examples/splat_lpa_label_propagation.rs @@ -76,6 +76,7 @@ fn splitmix64(state: &mut u64) -> u64 { struct PlantedGraph { n: u32, + #[allow(dead_code)] // planted-graph descriptor; read by the sibling probes k_communities: u32, /// `ground_truth[u]` = community id of node `u` (0..k_communities). ground_truth: Vec, @@ -152,10 +153,11 @@ fn lpa_superstep(graph: &PlantedGraph, labels: &[u16], next_labels: &mut [u16]) // Pick majority label; tie-break by sticking with `cur` if `cur` is // among the tied set (stability heuristic — converges faster). let max_count = tally.iter().map(|(_, c)| *c).max().unwrap_or(0); - let new_label = if max_count == 0 { - cur // isolated node — keep label - } else if tally.iter().any(|(l, c)| *l == cur && *c == max_count) { - cur // current label is among the tied max — stay + // isolated node (max_count == 0) keeps its label; so does a node whose + // current label is among the tied max — stay. + let new_label = if max_count == 0 || tally.iter().any(|(l, c)| *l == cur && *c == max_count) + { + cur } else { // pick lowest label id among tied for max tally diff --git a/crates/jc/examples/splat_perturbationslernen.rs b/crates/jc/examples/splat_perturbationslernen.rs index ce4d1359c..7516f16ba 100644 --- a/crates/jc/examples/splat_perturbationslernen.rs +++ b/crates/jc/examples/splat_perturbationslernen.rs @@ -152,6 +152,7 @@ fn sandwich(m: &Mat2, n: &Mat2) -> Mat2 { struct PlantedGraph { n: u32, + #[allow(dead_code)] // planted-graph descriptor; read by the sibling probes k_communities: u32, ground_truth: Vec, planes: Vec, @@ -347,7 +348,11 @@ fn main() { // Print only key checkpoints + saturation event (avoids 200 lines of output). fn should_print(i: usize, max: usize) -> bool { - i == 1 || i == max || (i <= 20 && i % 5 == 0) || (i <= 50 && i % 10 == 0) || i % 25 == 0 + i == 1 + || i == max + || (i <= 20 && i.is_multiple_of(5)) + || (i <= 50 && i.is_multiple_of(10)) + || i.is_multiple_of(25) } let t0 = std::time::Instant::now(); @@ -367,7 +372,7 @@ fn main() { } else { 1.0 }; - let alpha_iter = (1.0 - relative_change).max(0.0).min(1.0); + let alpha_iter = (1.0 - relative_change).clamp(0.0, 1.0); let saturated = alpha_iter >= ALPHA_SATURATION_THRESHOLD; if saturated { consecutive += 1; diff --git a/crates/jc/src/dueker_zoubouloglou.rs b/crates/jc/src/dueker_zoubouloglou.rs index 6adf1b87a..c4b4ea151 100644 --- a/crates/jc/src/dueker_zoubouloglou.rs +++ b/crates/jc/src/dueker_zoubouloglou.rs @@ -179,7 +179,7 @@ fn measure_trace(d: usize, n: usize, m: usize, phi: f64, seed: u64) -> (f64, f64 // ════════════════════════════════════════════════════════════════════════════ pub fn prove() -> PillarResult { - let (measured, predicted) = measure_trace(D, N, M, PHI, 0x0D_15_EA_5E_DEAD_BEEF); + let (measured, predicted) = measure_trace(D, N, M, PHI, 0x0D15_EA5E_DEAD_BEEF); let relative_error = (measured - predicted).abs() / predicted; let pass = relative_error < TOLERANCE; diff --git a/crates/jc/src/ewa_sandwich.rs b/crates/jc/src/ewa_sandwich.rs index bb3dfbf5a..a349eb750 100644 --- a/crates/jc/src/ewa_sandwich.rs +++ b/crates/jc/src/ewa_sandwich.rs @@ -52,11 +52,11 @@ //! the σ-codebook probe — heteroscedastic SPD around I, controlled spread) //! - Σ_0 = I (initial state); apply sandwich iteratively //! - Measure: -//! (a) PSD-preservation rate: fraction of (path, hop) pairs where -//! resulting Σ_n is numerically SPD (det > eps, both eigenvalues > 0) -//! (b) log-norm growth: ‖log(Σ_n)‖_F vs n; rate-of-growth indicator -//! (c) variance concentration: how does sample variance of ‖log(Σ_n)‖_F² -//! across paths scale with n? +//! (a) PSD-preservation rate: fraction of (path, hop) pairs where +//! resulting Σ_n is numerically SPD (det > eps, both eigenvalues > 0) +//! (b) log-norm growth: ‖log(Σ_n)‖_F vs n; rate-of-growth indicator +//! (c) variance concentration: how does sample variance of ‖log(Σ_n)‖_F² +//! across paths scale with n? //! //! # PASS criteria //! @@ -71,7 +71,7 @@ use crate::PillarResult; const N_PATHS: usize = 1_000; const PATH_LENGTH: usize = 10; -const SEED: u64 = 0xEDA_5A_DC_5A_DC; +const SEED: u64 = 0xEDA_5ADC_5ADC; // ════════════════════════════════════════════════════════════════════════════ // Deterministic RNG (consistent with other pillars) @@ -237,6 +237,7 @@ fn sample_step_sigma(state: &mut u64, sigma_step: f64) -> Spd2 { #[derive(Clone, Copy, Debug)] struct PathResult { + #[cfg_attr(not(test), allow(dead_code))] final_sigma: Spd2, log_norm_sq: f64, // ‖log(Σ_n)‖_F^2 psd_hops: usize, // how many of the `length` hops kept Σ in SPD diff --git a/crates/jc/src/ewa_sandwich_3d.rs b/crates/jc/src/ewa_sandwich_3d.rs index ba77e3756..e44963e71 100644 --- a/crates/jc/src/ewa_sandwich_3d.rs +++ b/crates/jc/src/ewa_sandwich_3d.rs @@ -59,7 +59,7 @@ //! //! - 1000 paths × 10 hops, σ_step = 0.2, PSD eps = 1e-12 //! - Same splitmix64/rand_uniform/rand_normal RNG declared locally -//! - SEED = 0xEDA_5A_DC_5A_DD (one byte higher than Pillar 6's 0xEDA_5A_DC_5A_DC) +//! - SEED = 0xEDA_5ADC_5ADD (one byte higher than Pillar 6's 0xEDA_5A_DC_5A_DC) //! - Σ_0 = I; each hop: step ~ from_scale_quat(exp-normal scales, uniform quat) //! - M = sqrt(step); Σ_{n+1} = M · Σ_n · Mᵀ @@ -67,7 +67,7 @@ use crate::PillarResult; const N_PATHS: usize = 1_000; const PATH_LENGTH: usize = 10; -const SEED: u64 = 0xEDA_5A_DC_5A_DD; +const SEED: u64 = 0xEDA_5ADC_5ADD; // ════════════════════════════════════════════════════════════════════════════ // Deterministic RNG (consistent with other pillars) @@ -438,6 +438,7 @@ fn sample_step_sigma(state: &mut u64, sigma_step: f64) -> Spd3 { #[derive(Clone, Copy, Debug)] struct PathResult { + #[cfg_attr(not(test), allow(dead_code))] final_sigma: Spd3, log_norm_sq: f64, psd_hops: usize, diff --git a/crates/jc/src/koestenberger.rs b/crates/jc/src/koestenberger.rs index c3dc28327..f192c8a7c 100644 --- a/crates/jc/src/koestenberger.rs +++ b/crates/jc/src/koestenberger.rs @@ -54,7 +54,7 @@ //! - μ = I (identity) is both the population mean and each μ_k by construction //! - Heteroscedastic: σ_k = 0.3 / √(k+1) — variance shrinks per sample index //! - X_k = R(θ_k) · diag(exp(σ_k·n1), exp(σ_k·n2)) · R(θ_k)ᵀ -//! with θ_k uniform on [0,π) and n1, n2 ~ N(0,1) iid +//! with θ_k uniform on [0,π) and n1, n2 ~ N(0,1) iid //! - Var(X_k) = E[d²(X_k, μ_k)] = 2 σ_k² (rotational symmetry argument) //! - Σ d(μ_k, μ) = 0 (we set μ_k = μ = I, so the 6·D_n term vanishes) //! - Predicted bound therefore reduces to (1/n²) · Σ Var(X_k) = (2/n²) · Σ σ_k² @@ -256,7 +256,7 @@ pub fn prove() -> PillarResult { // Monte Carlo estimate of E[d²(S_n, I)]. let mu = Spd2::I; - let mut state: u64 = 0xC0FFEE_BEEF_5EED; + let mut state: u64 = 0xC0_FFEE_BEEF_5EED; let mut sum_sq_dist = 0.0f64; let mut samples_buf = Vec::with_capacity(N_SAMPLES); diff --git a/crates/jc/src/lib.rs b/crates/jc/src/lib.rs index 84bb426df..7a17c6766 100644 --- a/crates/jc/src/lib.rs +++ b/crates/jc/src/lib.rs @@ -8,14 +8,14 @@ //! 3. Optimal collocation without aliasing (φ-Weyl) //! 4. Fast prolongation convergence (γ+φ preconditioner) //! 5. Bounded noise floor under correct dependence model (Jirak 2016) -//! 5b. Pearl 2³ mask-classification accuracy (three-plane Index regime -//! vs CAM-PQ-shaped bundled regime) — the task-level downstream -//! consequence of pillar 5's sup-error inflation. +//! - 5b. Pearl 2³ mask-classification accuracy (three-plane Index regime +//! vs CAM-PQ-shaped bundled regime) — the task-level downstream +//! consequence of pillar 5's sup-error inflation. //! 7. Concentration on Hadamard space (Köstenberger-Stark 2024) //! 8. Hilbert-space CLT for AR(1) (Düker-Zoubouloglou 2024) //! 9. EWA-sandwich Σ-push-forward along multi-hop edge paths -//! 9b. EWA-Sandwich 3D: Σ-push-forward on symmetric 3×3 SPD covariances -//! (3D analogue of pillar 9; certifies J·W·Σ·Wᵀ·Jᵀ for ndarray::hpc::splat3d) +//! - 9b. EWA-Sandwich 3D: Σ-push-forward on symmetric 3×3 SPD covariances +//! (3D analogue of pillar 9; certifies J·W·Σ·Wᵀ·Jᵀ for ndarray::hpc::splat3d) //! 10. Nested-distance Lipschitz on Sigma DN-trees (Pflug-Pichler 2012) //! — certifies CAM-PQ tree quantization preserves FreeEnergy within Lε. //! 11. Signature uniqueness on tree-quotient (Hambly-Lyons 2010) @@ -130,8 +130,11 @@ impl PillarResult { } } +/// A named pillar probe: label plus the function that runs it. +type Pillar = (&'static str, fn() -> PillarResult); + pub fn run_all_pillars() -> Vec { - let pillars: Vec<(&str, fn() -> PillarResult)> = vec![ + let pillars: Vec = vec![ ( "E-SUBSTRATE-1: bundle associativity @ d=10000", substrate::prove, diff --git a/crates/jc/src/pearl.rs b/crates/jc/src/pearl.rs index 056a17330..acb0a1a1e 100644 --- a/crates/jc/src/pearl.rs +++ b/crates/jc/src/pearl.rs @@ -79,6 +79,7 @@ fn hamming(a: &[u8], b: &[u8]) -> u32 { /// Classify Pearl mask from three independent lossless planes. /// Each plane carries exactly one role's binding — no interference. +#[allow(clippy::too_many_arguments)] // probe harness: three planes + three role keys + content + threshold fn classify_three_planes( plane_s: &[u8], plane_p: &[u8], diff --git a/crates/jc/src/pflug.rs b/crates/jc/src/pflug.rs index c6c48fbb4..45af3d20d 100644 --- a/crates/jc/src/pflug.rs +++ b/crates/jc/src/pflug.rs @@ -141,6 +141,7 @@ impl BinaryTree { } /// Stage of node k (0-indexed; root is stage 0). + #[cfg(test)] fn stage(k: usize) -> usize { // Stage = floor(log2(k+1)). let mut s = 0; diff --git a/crates/jc/src/probe_p1_gamma_phase.rs b/crates/jc/src/probe_p1_gamma_phase.rs index a652999a4..6d80adf81 100644 --- a/crates/jc/src/probe_p1_gamma_phase.rs +++ b/crates/jc/src/probe_p1_gamma_phase.rs @@ -291,7 +291,7 @@ mod tests { fn apply_offset_wraps_modulo_one() { // value 0.9 + offset k=4 (4 * 1/(4φ) = 1/φ ≈ 0.618) → 1.518 mod 1 = 0.518 let r = apply_offset(0.9, 4); - assert!(r >= 0.0 && r < 1.0, "result out of [0,1): {r}"); + assert!((0.0..1.0).contains(&r), "result out of [0,1): {r}"); } #[test] diff --git a/crates/jc/src/sigma_codebook_probe.rs b/crates/jc/src/sigma_codebook_probe.rs index 6c967b908..03d3b29cf 100644 --- a/crates/jc/src/sigma_codebook_probe.rs +++ b/crates/jc/src/sigma_codebook_probe.rs @@ -461,7 +461,7 @@ mod tests { ); assert_eq!(centroids.len(), 3); let used = { - let mut seen = vec![false; 3]; + let mut seen = [false; 3]; for &a in &assignments { seen[a] = true; } diff --git a/crates/jc/src/weyl.rs b/crates/jc/src/weyl.rs index 4eabfea97..9eb7d1796 100644 --- a/crates/jc/src/weyl.rs +++ b/crates/jc/src/weyl.rs @@ -11,7 +11,7 @@ use crate::PillarResult; const PHI_INV: f64 = 0.618_033_988_749_894_9; // 1/φ = (√5 - 1) / 2 -const QUINTENZIRKEL: f64 = 0.584_962_500_721_156_0; // log₂(3/2) ≈ 0.585 +const QUINTENZIRKEL: f64 = 0.584_962_500_721_156; // log₂(3/2) ≈ 0.585 fn frac(x: f64) -> f64 { x - x.floor()