Skip to content

perturbation-sim B1: finite-gate the spectral-gap NaN landmine (Davis–Kahan / λ₂→0)#524

Merged
AdaWorldAPI merged 1 commit into
mainfrom
claude/perturbation-soa-nan-gate-witness
Jun 17, 2026
Merged

perturbation-sim B1: finite-gate the spectral-gap NaN landmine (Davis–Kahan / λ₂→0)#524
AdaWorldAPI merged 1 commit into
mainfrom
claude/perturbation-soa-nan-gate-witness

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

What

Finite-gates the spectral-gap NaN landmine in the perturbation-sim outage model — "one NaN less" on the SoA substrate, applied to the regime the model exists to capture. Additive, behaviour-preserving in the healthy regime; gates only the degenerate (fragmentation / λ₂→0) path.

B1 — spectral NaN audit + finite-gate (shipped)

Audited every division by a spectral gap / λ₂ / eigenvalue-difference / norm across all spectral modules. The crate was already well-defended (eigen's pseudo_apply/pseudo_inverse use a relative rel_tol·λ_max cutoff; lodf/kirchhoff_index/stats/timing/buffer/chaoda/model are guarded). The real defect was in the Davis–Kahan path: naked, absolute, inconsistent ε-guards that caught 0/0 but let a tiny-positive noisy gap slip through as a silently-wrong finite "bound."

Sites gated (floor the denominator after the subtract, relative to λ_max — the entropy_ladder::residue_surprise pattern, PR #221):

Site Gate Justification
perturbation.rs davis_kahan_bound gap floored after the min at SPECTRAL_GAP_FLOOR·λ_max; ≤ floor ⇒ FRAGMENTATION_SENTINEL gap→0 = fragmentation ⇒ sinθ ≤ ‖E‖/0 = +∞; a finite, finiteness-checkable sentinel that preserves the signal, never NaN
perturbation.rs connectivity_loss floor + .clamp(0,1) 0/0 = "no connectivity to lose" ⇒ 0; clamp stops a noisy λ₂ exceeding the fraction's domain
rolling_floor.rs weyl_over_fiedler floor unified with SPECTRAL_GAP_FLOOR; / λ₂.abs() same λ₂→0 precursor; .abs()+.max(0) keep the instability ratio non-negative

Tests: 91 → 95 (manifest-path; perturbation-sim is an excluded crate). New: blackout_precursor_regime_is_never_nan, disconnected_graph_spectral_outputs_are_nan_free, weyl_over_fiedler_is_nan_free_at_the_precursor (finiteness PASS), and healthy_grid_davis_kahan_is_finite_and_bounds_rotation (normal-regime parity PASS, non-vacuous). Key discovery: a symmetric ring's Fiedler mode is legitimately doubly-degenerate (λ₂=λ₃ ⇒ gap=0), so the sentinel is reachable in normal use — confirming the gate is signal-preserving, not a corner-case patch. clippy -D warnings clean; fmt clean; examples build.

B2 — witness-arc → contract witness_table: deferred (needs an operator decision)

The contract WitnessTable is an address-resolution primitive (W-slot get/set), not an arc evaluator — there is no additive hook to wire witness.rs's particle == wave Parseval oracle into. Doing so requires a new contract trait (WitnessArcEvaluator) on a new field-carrying typemore than additive, crossing the "no new trait/bridge" iron rule (and witness.rs's own doc calls it "a separate, gated step"). Not forced; the exact surface is documented in AGENT_LOG.md for the operator's call.

Adjacent finding (flagged, out of scope)

acflow.rs (AC Newton–Raphson) has its own division landmines — Cx::recip ÷ |z|² (zero-impedance line) and Jacobian ÷ v[i] (NR divergence → v→0). These are voltage-collapse, not spectral-fragmentation, and want a different gate (pivot guard + converged:false). Recorded in E-SPECTRAL-GAP-NAN-1 for a future AC-flow pass — not touched here.

Board: EPIPHANIES.md E-SPECTRAL-GAP-NAN-1 + AGENT_LOG.md, same commit.

🤖 Generated with Claude Code


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@AdaWorldAPI, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 38 minutes and 7 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e82cca94-4bbc-49a0-a738-12e2a8d31418

📥 Commits

Reviewing files that changed from the base of the PR and between 64c77ad and 69a1189.

📒 Files selected for processing (5)
  • .claude/board/AGENT_LOG.md
  • .claude/board/EPIPHANIES.md
  • crates/perturbation-sim/src/lib.rs
  • crates/perturbation-sim/src/perturbation.rs
  • crates/perturbation-sim/src/rolling_floor.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

The spectral half of perturbation-sim divides by a vanishing spectral
gap precisely at blackout onset: the Davis-Kahan Fiedler rotation bound
sinθ ≤ ‖E‖₂/gap and the mode-instability modifier Δλ·(1/λ₂) both blow
up as gap→0 / λ₂→0 — the exact fragmentation regime the model exists to
capture. Same NaN class as ndarray entropy_ladder::residue_surprise
(PR #221): a subtracted denominator collapsing to 0 → 0/0, or a
tiny-positive denominator slipping past a naked `gap > ε` test and
producing a silently-wrong finite "bound".

Fix (the entropy_ladder pattern): floor the denominator AFTER the
subtract-and-min that builds it, relative to λ_max, then divide
unconditionally. gap ≤ SPECTRAL_GAP_FLOOR·λ_max ⇒ spectral degeneracy ⇒
FRAGMENTATION_SENTINEL (= +∞, the workspace's documented divergence
signal — finiteness-checkable, never NaN). connectivity_loss gated by
the floor + clamped to [0,1]; weyl_over_fiedler floor unified, divides
by λ₂.abs(), numerator .max(0.0).

Sentinel, not swallow: gap=0 is a real result (the Fiedler vector may
rotate arbitrarily ⇒ sinθ ≤ ‖E‖₂/0 = +∞). The gate guarantees every
spectral output is either a trustworthy finite number or the explicit
+∞ divergence signal — never NaN, never a silently-wrong finite. A
symmetric ring (degenerate Fiedler mode, λ₂=λ₃) confirmed the sentinel
is reachable in normal use, not just a corner case.

+4 regression tests (91 → 95 green): NaN-freedom across the precursor
regime (near-zero bridge, disconnected graph, degenerate ring, λ₂∈
{0,±1e-14,…}) + sentinel-correctness on fragmentation + normal-regime
PARITY (asymmetric weighted path, separated λ₂, non-vacuity asserted)
proving the gate touches ONLY the singular path.

B2 (witness arc → contract witness_table evaluator): assessed,
STOP-and-reported. The contract WitnessTable is a (mailbox_ref,
spo_fact_ref) address-resolution primitive, NOT an arc evaluator — no
hook exists; wiring would require a NEW contract trait
(WitnessArcEvaluator) + a field-carrying type, which is more than
additive. Did not force it (witness.rs's own doc names it a separate
gated step). Exact surface documented in AGENT_LOG for operator
decision.

Behaviour-preserving in the normal regime; gated only the degenerate
path. clippy -D warnings clean, fmt clean, examples build. Board:
EPIPHANIES E-SPECTRAL-GAP-NAN-1 + AGENT_LOG prepended in this commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi
@AdaWorldAPI AdaWorldAPI force-pushed the claude/perturbation-soa-nan-gate-witness branch from 398e3d4 to 69a1189 Compare June 17, 2026 22:03
@AdaWorldAPI AdaWorldAPI merged commit e95288d into main Jun 17, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants