mirror of
https://github.com/elder-plinius/OBLITERATUS.git
synced 2026-08-30 22:50:46 +02:00
fix: make spectral evidence fail inconclusive (#183)
This commit is contained in:
@@ -95,3 +95,32 @@ assert "🔴" in card
|
||||
check=False,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
@pytest.mark.operator_ui
|
||||
def test_result_card_exposes_spectral_inconclusive_reason():
|
||||
script = r'''
|
||||
from types import SimpleNamespace
|
||||
|
||||
import app
|
||||
|
||||
pipeline = SimpleNamespace(
|
||||
_quality_metrics={
|
||||
"spectral_certification": "INCONCLUSIVE",
|
||||
"spectral_diagnostic_reason": "insufficient_samples",
|
||||
},
|
||||
_strong_layers=[1],
|
||||
)
|
||||
card = app._format_obliteration_metrics(pipeline, "advanced", "1s")
|
||||
assert "Spectral Diagnostic" in card
|
||||
assert "INCONCLUSIVE (insufficient_samples)" in card
|
||||
assert "⚪" in card
|
||||
'''
|
||||
result = subprocess.run(
|
||||
[sys.executable, "-c", script],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=60,
|
||||
check=False,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
@@ -10,6 +10,7 @@ from __future__ import annotations
|
||||
|
||||
import math
|
||||
|
||||
import pytest
|
||||
import torch
|
||||
|
||||
from obliteratus.analysis.riemannian_manifold import (
|
||||
@@ -687,6 +688,57 @@ class TestSpectralCertification:
|
||||
assert result.confidence < 0.95
|
||||
assert "inconclusive" in result.recommendation.lower()
|
||||
|
||||
def test_qwen_width_dual_space_case_is_inconclusive_not_zero_threshold_red(self):
|
||||
"""The production n=40, d=5120 regime cannot self-certify via signal size."""
|
||||
torch.manual_seed(42)
|
||||
harmful = torch.randn(20, 5120) * 0.3
|
||||
harmless = torch.randn(20, 5120) * 0.3
|
||||
|
||||
result = SpectralCertifier().certify(harmful, harmless)
|
||||
|
||||
assert result.level == CertificationLevel.INCONCLUSIVE
|
||||
assert result.diagnostic_reason == "insufficient_samples"
|
||||
assert result.effective_noise_rank > 1
|
||||
assert math.isfinite(result.bbp_threshold)
|
||||
assert result.bbp_threshold > 0
|
||||
assert result.n_samples_required >= math.ceil(math.sqrt(5120))
|
||||
|
||||
def test_zero_noise_scale_is_machine_readable_inconclusive(self):
|
||||
harmful = torch.ones(30, 32)
|
||||
harmless = torch.ones(30, 32)
|
||||
|
||||
result = SpectralCertifier().certify(harmful, harmless)
|
||||
|
||||
assert result.level == CertificationLevel.INCONCLUSIVE
|
||||
assert result.diagnostic_reason == "zero_or_non_finite_noise_scale"
|
||||
assert result.effective_noise_rank == 0
|
||||
assert result.is_sample_sufficient is False
|
||||
|
||||
def test_non_finite_activations_are_machine_readable_inconclusive(self):
|
||||
harmful = torch.randn(30, 32)
|
||||
harmless = torch.randn(30, 32)
|
||||
harmful[0, 0] = float("nan")
|
||||
|
||||
result = SpectralCertifier().certify(harmful, harmless)
|
||||
|
||||
assert result.level == CertificationLevel.INCONCLUSIVE
|
||||
assert result.diagnostic_reason == "non_finite_activations"
|
||||
assert result.is_sample_sufficient is False
|
||||
assert math.isfinite(result.bbp_threshold)
|
||||
assert math.isfinite(result.leading_eigenvalue)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("harmful", "harmless", "message"),
|
||||
[
|
||||
(torch.zeros(2, 2, 2), torch.zeros(2, 2), "2-D"),
|
||||
(torch.zeros(2, 3), torch.zeros(2, 4), "hidden width"),
|
||||
(torch.zeros(1, 3), torch.zeros(2, 3), "two samples"),
|
||||
],
|
||||
)
|
||||
def test_invalid_activation_shapes_fail_closed(self, harmful, harmless, message):
|
||||
with pytest.raises(ValueError, match=message):
|
||||
SpectralCertifier().certify(harmful, harmless)
|
||||
|
||||
def test_overall_prefers_sufficient_red_over_inconclusive(self):
|
||||
"""A reliable RED layer remains actionable in a mixed result set."""
|
||||
torch.manual_seed(42)
|
||||
|
||||
@@ -231,6 +231,22 @@ class TestBuildReport:
|
||||
"refusal_rate": "measured",
|
||||
}
|
||||
|
||||
def test_spectral_inconclusive_reason_and_rank_are_public_metrics(self):
|
||||
report = build_report(**self._base_kwargs(quality_metrics={
|
||||
"spectral_certification": "INCONCLUSIVE",
|
||||
"spectral_diagnostic_reason": "insufficient_samples",
|
||||
"spectral_effective_noise_rank": 38,
|
||||
"spectral_samples_required": 72,
|
||||
}))
|
||||
|
||||
assert report["quality_metrics"] == {
|
||||
"spectral_certification": "INCONCLUSIVE",
|
||||
"spectral_diagnostic_reason": "insufficient_samples",
|
||||
"spectral_effective_noise_rank": 38.0,
|
||||
"spectral_samples_required": 72.0,
|
||||
}
|
||||
assert set(report["quality_metric_status"].values()) == {"measured"}
|
||||
|
||||
def test_public_payload_redacts_paths_tokens_and_secret_keys(self):
|
||||
report = build_report(**self._base_kwargs(
|
||||
architecture="/private/models/LlamaForCausalLM",
|
||||
|
||||
Reference in New Issue
Block a user