invarlock 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- invarlock/__init__.py +33 -0
- invarlock/__main__.py +10 -0
- invarlock/_data/runtime/profiles/ci_cpu.yaml +15 -0
- invarlock/_data/runtime/profiles/release.yaml +23 -0
- invarlock/_data/runtime/tiers.yaml +76 -0
- invarlock/adapters/__init__.py +102 -0
- invarlock/adapters/_capabilities.py +45 -0
- invarlock/adapters/auto.py +99 -0
- invarlock/adapters/base.py +530 -0
- invarlock/adapters/base_types.py +85 -0
- invarlock/adapters/hf_bert.py +852 -0
- invarlock/adapters/hf_gpt2.py +403 -0
- invarlock/adapters/hf_llama.py +485 -0
- invarlock/adapters/hf_mixin.py +383 -0
- invarlock/adapters/hf_onnx.py +112 -0
- invarlock/adapters/hf_t5.py +137 -0
- invarlock/adapters/py.typed +1 -0
- invarlock/assurance/__init__.py +43 -0
- invarlock/cli/__init__.py +8 -0
- invarlock/cli/__main__.py +8 -0
- invarlock/cli/_evidence.py +25 -0
- invarlock/cli/_json.py +75 -0
- invarlock/cli/adapter_auto.py +162 -0
- invarlock/cli/app.py +287 -0
- invarlock/cli/commands/__init__.py +26 -0
- invarlock/cli/commands/certify.py +403 -0
- invarlock/cli/commands/doctor.py +1358 -0
- invarlock/cli/commands/explain_gates.py +151 -0
- invarlock/cli/commands/export_html.py +100 -0
- invarlock/cli/commands/plugins.py +1331 -0
- invarlock/cli/commands/report.py +354 -0
- invarlock/cli/commands/run.py +4146 -0
- invarlock/cli/commands/verify.py +1040 -0
- invarlock/cli/config.py +396 -0
- invarlock/cli/constants.py +68 -0
- invarlock/cli/device.py +92 -0
- invarlock/cli/doctor_helpers.py +74 -0
- invarlock/cli/errors.py +6 -0
- invarlock/cli/overhead_utils.py +60 -0
- invarlock/cli/provenance.py +66 -0
- invarlock/cli/utils.py +41 -0
- invarlock/config.py +56 -0
- invarlock/core/__init__.py +62 -0
- invarlock/core/abi.py +15 -0
- invarlock/core/api.py +274 -0
- invarlock/core/auto_tuning.py +317 -0
- invarlock/core/bootstrap.py +226 -0
- invarlock/core/checkpoint.py +221 -0
- invarlock/core/contracts.py +73 -0
- invarlock/core/error_utils.py +64 -0
- invarlock/core/events.py +298 -0
- invarlock/core/exceptions.py +95 -0
- invarlock/core/registry.py +481 -0
- invarlock/core/retry.py +146 -0
- invarlock/core/runner.py +2041 -0
- invarlock/core/types.py +154 -0
- invarlock/edits/__init__.py +12 -0
- invarlock/edits/_edit_utils.py +249 -0
- invarlock/edits/_external_utils.py +268 -0
- invarlock/edits/noop.py +47 -0
- invarlock/edits/py.typed +1 -0
- invarlock/edits/quant_rtn.py +801 -0
- invarlock/edits/registry.py +166 -0
- invarlock/eval/__init__.py +23 -0
- invarlock/eval/bench.py +1207 -0
- invarlock/eval/bootstrap.py +50 -0
- invarlock/eval/data.py +2052 -0
- invarlock/eval/metrics.py +2167 -0
- invarlock/eval/primary_metric.py +767 -0
- invarlock/eval/probes/__init__.py +24 -0
- invarlock/eval/probes/fft.py +139 -0
- invarlock/eval/probes/mi.py +213 -0
- invarlock/eval/probes/post_attention.py +323 -0
- invarlock/eval/providers/base.py +67 -0
- invarlock/eval/providers/seq2seq.py +111 -0
- invarlock/eval/providers/text_lm.py +113 -0
- invarlock/eval/providers/vision_text.py +93 -0
- invarlock/eval/py.typed +1 -0
- invarlock/guards/__init__.py +18 -0
- invarlock/guards/_contracts.py +9 -0
- invarlock/guards/invariants.py +640 -0
- invarlock/guards/policies.py +805 -0
- invarlock/guards/py.typed +1 -0
- invarlock/guards/rmt.py +2097 -0
- invarlock/guards/spectral.py +1419 -0
- invarlock/guards/tier_config.py +354 -0
- invarlock/guards/variance.py +3298 -0
- invarlock/guards_ref/__init__.py +15 -0
- invarlock/guards_ref/rmt_ref.py +40 -0
- invarlock/guards_ref/spectral_ref.py +135 -0
- invarlock/guards_ref/variance_ref.py +60 -0
- invarlock/model_profile.py +353 -0
- invarlock/model_utils.py +221 -0
- invarlock/observability/__init__.py +10 -0
- invarlock/observability/alerting.py +535 -0
- invarlock/observability/core.py +546 -0
- invarlock/observability/exporters.py +565 -0
- invarlock/observability/health.py +588 -0
- invarlock/observability/metrics.py +457 -0
- invarlock/observability/py.typed +1 -0
- invarlock/observability/utils.py +553 -0
- invarlock/plugins/__init__.py +12 -0
- invarlock/plugins/hello_guard.py +33 -0
- invarlock/plugins/hf_awq_adapter.py +82 -0
- invarlock/plugins/hf_bnb_adapter.py +79 -0
- invarlock/plugins/hf_gptq_adapter.py +78 -0
- invarlock/plugins/py.typed +1 -0
- invarlock/py.typed +1 -0
- invarlock/reporting/__init__.py +7 -0
- invarlock/reporting/certificate.py +3221 -0
- invarlock/reporting/certificate_schema.py +244 -0
- invarlock/reporting/dataset_hashing.py +215 -0
- invarlock/reporting/guards_analysis.py +948 -0
- invarlock/reporting/html.py +32 -0
- invarlock/reporting/normalizer.py +235 -0
- invarlock/reporting/policy_utils.py +517 -0
- invarlock/reporting/primary_metric_utils.py +265 -0
- invarlock/reporting/render.py +1442 -0
- invarlock/reporting/report.py +903 -0
- invarlock/reporting/report_types.py +278 -0
- invarlock/reporting/utils.py +175 -0
- invarlock/reporting/validate.py +631 -0
- invarlock/security.py +176 -0
- invarlock/sparsity_utils.py +323 -0
- invarlock/utils/__init__.py +150 -0
- invarlock/utils/digest.py +45 -0
- invarlock-0.2.0.dist-info/METADATA +586 -0
- invarlock-0.2.0.dist-info/RECORD +132 -0
- invarlock-0.2.0.dist-info/WHEEL +5 -0
- invarlock-0.2.0.dist-info/entry_points.txt +20 -0
- invarlock-0.2.0.dist-info/licenses/LICENSE +201 -0
- invarlock-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
# mypy: ignore-errors
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import copy
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from invarlock.core.auto_tuning import TIER_POLICIES
|
|
10
|
+
|
|
11
|
+
from .report_types import RunReport
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _compute_variance_policy_digest(policy: dict[str, Any]) -> str:
|
|
15
|
+
"""Compute a stable digest for the variance guard policy knobs."""
|
|
16
|
+
canonical_keys = [
|
|
17
|
+
"deadband",
|
|
18
|
+
"min_abs_adjust",
|
|
19
|
+
"max_scale_step",
|
|
20
|
+
"min_effect_lognll",
|
|
21
|
+
"predictive_one_sided",
|
|
22
|
+
"topk_backstop",
|
|
23
|
+
"max_adjusted_modules",
|
|
24
|
+
]
|
|
25
|
+
canonical_payload = {
|
|
26
|
+
key: policy.get(key) for key in canonical_keys if key in policy
|
|
27
|
+
}
|
|
28
|
+
if not canonical_payload:
|
|
29
|
+
return ""
|
|
30
|
+
serialized = json.dumps(canonical_payload, sort_keys=True, separators=(",", ":"))
|
|
31
|
+
return hashlib.sha256(serialized.encode("utf-8")).hexdigest()[:16]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _compute_thresholds_payload(
|
|
35
|
+
tier: str, resolved_policy: dict[str, Any]
|
|
36
|
+
) -> dict[str, Any]:
|
|
37
|
+
"""Build canonical thresholds payload for digest stability."""
|
|
38
|
+
from .certificate import TIER_RATIO_LIMITS # local to avoid cycles
|
|
39
|
+
|
|
40
|
+
tier_lc = (tier or "balanced").lower()
|
|
41
|
+
ratio_limit_base = float(TIER_RATIO_LIMITS.get(tier_lc, 1.10))
|
|
42
|
+
tier_policy = TIER_POLICIES.get(tier_lc, {}) if isinstance(tier_lc, str) else {}
|
|
43
|
+
metrics_policy = (
|
|
44
|
+
tier_policy.get("metrics", {}) if isinstance(tier_policy, dict) else {}
|
|
45
|
+
)
|
|
46
|
+
pm_policy = (
|
|
47
|
+
metrics_policy.get("pm_ratio", {}) if isinstance(metrics_policy, dict) else {}
|
|
48
|
+
)
|
|
49
|
+
acc_policy = (
|
|
50
|
+
metrics_policy.get("accuracy", {}) if isinstance(metrics_policy, dict) else {}
|
|
51
|
+
)
|
|
52
|
+
variance_policy = (
|
|
53
|
+
resolved_policy.get("variance", {}) if isinstance(resolved_policy, dict) else {}
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
payload = {
|
|
57
|
+
"tier": tier_lc,
|
|
58
|
+
"pm_ratio": {
|
|
59
|
+
"ratio_limit_base": ratio_limit_base,
|
|
60
|
+
"min_tokens": int(pm_policy.get("min_tokens", 0) or 0),
|
|
61
|
+
"min_token_fraction": float(
|
|
62
|
+
pm_policy.get("min_token_fraction", 0.0) or 0.0
|
|
63
|
+
),
|
|
64
|
+
"hysteresis_ratio": float(pm_policy.get("hysteresis_ratio", 0.0) or 0.0),
|
|
65
|
+
},
|
|
66
|
+
"accuracy": {
|
|
67
|
+
"delta_min_pp": float(acc_policy.get("delta_min_pp", -1.0) or -1.0),
|
|
68
|
+
"min_examples": int(acc_policy.get("min_examples", 200) or 200),
|
|
69
|
+
"min_examples_fraction": float(
|
|
70
|
+
acc_policy.get("min_examples_fraction", 0.0) or 0.0
|
|
71
|
+
),
|
|
72
|
+
"hysteresis_delta_pp": float(
|
|
73
|
+
acc_policy.get("hysteresis_delta_pp", 0.0) or 0.0
|
|
74
|
+
),
|
|
75
|
+
},
|
|
76
|
+
"variance": {
|
|
77
|
+
"min_effect_lognll": float(
|
|
78
|
+
variance_policy.get("min_effect_lognll", 0.0) or 0.0
|
|
79
|
+
)
|
|
80
|
+
},
|
|
81
|
+
}
|
|
82
|
+
return payload
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _compute_thresholds_hash(payload: dict[str, Any]) -> str:
|
|
86
|
+
canonical = json.dumps(payload, sort_keys=True, separators=(",", ":"))
|
|
87
|
+
return hashlib.sha256(canonical.encode("utf-8")).hexdigest()[:16]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _promote_legacy_multiple_testing_key(payload: dict[str, Any]) -> None:
|
|
91
|
+
"""Promote legacy 'multipletesting' to 'multiple_testing' in-place if present."""
|
|
92
|
+
try:
|
|
93
|
+
legacy_mt = payload.pop("multipletesting", None)
|
|
94
|
+
if legacy_mt is not None and "multiple_testing" not in payload:
|
|
95
|
+
payload["multiple_testing"] = legacy_mt
|
|
96
|
+
except Exception:
|
|
97
|
+
pass
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _resolve_policy_tier(report: RunReport) -> str:
|
|
101
|
+
"""Resolve the policy tier from report metadata or context."""
|
|
102
|
+
tier: Any = None
|
|
103
|
+
try:
|
|
104
|
+
meta = report.get("meta", {}) if isinstance(report, dict) else {}
|
|
105
|
+
auto_cfg: dict[str, Any] | None = (
|
|
106
|
+
meta.get("auto", {}) if isinstance(meta, dict) else {}
|
|
107
|
+
)
|
|
108
|
+
tier = auto_cfg.get("tier") or meta.get("policy_tier")
|
|
109
|
+
if not tier:
|
|
110
|
+
context = report.get("context", {}) if isinstance(report, dict) else {}
|
|
111
|
+
if isinstance(context, dict):
|
|
112
|
+
tier = context.get("policy_tier") or (
|
|
113
|
+
context.get("auto", {})
|
|
114
|
+
if isinstance(context.get("auto"), dict)
|
|
115
|
+
else {}
|
|
116
|
+
).get("tier")
|
|
117
|
+
if not tier:
|
|
118
|
+
tier = "balanced"
|
|
119
|
+
return str(tier).lower()
|
|
120
|
+
except Exception:
|
|
121
|
+
return "balanced"
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _format_family_caps(caps: Any) -> dict[str, dict[str, float]]:
|
|
125
|
+
formatted: dict[str, dict[str, float]] = {}
|
|
126
|
+
if isinstance(caps, dict):
|
|
127
|
+
for family, data in caps.items():
|
|
128
|
+
family_name = str(family)
|
|
129
|
+
if isinstance(data, dict):
|
|
130
|
+
kappa_val = data.get("kappa")
|
|
131
|
+
if isinstance(kappa_val, int | float):
|
|
132
|
+
try:
|
|
133
|
+
formatted[family_name] = {"kappa": float(kappa_val)}
|
|
134
|
+
except Exception:
|
|
135
|
+
pass
|
|
136
|
+
elif isinstance(data, int | float):
|
|
137
|
+
try:
|
|
138
|
+
formatted[family_name] = {"kappa": float(data)}
|
|
139
|
+
except Exception:
|
|
140
|
+
pass
|
|
141
|
+
return formatted
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _format_epsilon_map(epsilon_map: Any) -> dict[str, float]:
|
|
145
|
+
formatted: dict[str, float] = {}
|
|
146
|
+
if isinstance(epsilon_map, dict):
|
|
147
|
+
for family, value in epsilon_map.items():
|
|
148
|
+
if isinstance(value, int | float):
|
|
149
|
+
try:
|
|
150
|
+
formatted[str(family)] = float(value)
|
|
151
|
+
except Exception:
|
|
152
|
+
pass
|
|
153
|
+
return formatted
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def _build_resolved_policies(
|
|
157
|
+
tier: str, spectral: dict[str, Any], rmt: dict[str, Any], variance: dict[str, Any]
|
|
158
|
+
) -> dict[str, Any]:
|
|
159
|
+
"""Merge tier defaults with observed policies to surface the resolved configuration."""
|
|
160
|
+
tier_key = (tier or "balanced").lower()
|
|
161
|
+
base = copy.deepcopy(TIER_POLICIES.get(tier_key, TIER_POLICIES.get("balanced", {})))
|
|
162
|
+
|
|
163
|
+
resolved: dict[str, Any] = {}
|
|
164
|
+
|
|
165
|
+
def _safe_float(value: Any, default: float) -> float:
|
|
166
|
+
try:
|
|
167
|
+
return float(value)
|
|
168
|
+
except (TypeError, ValueError):
|
|
169
|
+
return float(default)
|
|
170
|
+
|
|
171
|
+
def _safe_int(value: Any, default: int) -> int:
|
|
172
|
+
try:
|
|
173
|
+
return int(value)
|
|
174
|
+
except (TypeError, ValueError):
|
|
175
|
+
return int(default)
|
|
176
|
+
|
|
177
|
+
# Spectral guard
|
|
178
|
+
base_spectral = (
|
|
179
|
+
copy.deepcopy(base.get("spectral", {})) if isinstance(base, dict) else {}
|
|
180
|
+
)
|
|
181
|
+
spectral_resolved: dict[str, Any] = {}
|
|
182
|
+
if isinstance(base_spectral, dict):
|
|
183
|
+
spectral_resolved.update(base_spectral)
|
|
184
|
+
spectral_caps = spectral.get("family_caps") or spectral_resolved.get("family_caps")
|
|
185
|
+
from .policy_utils import _format_family_caps as _ffc # self import safe
|
|
186
|
+
|
|
187
|
+
spectral_resolved["family_caps"] = _ffc(spectral_caps)
|
|
188
|
+
# Prefer observed policy sigma_quantile (accepting legacy aliases), then fallback
|
|
189
|
+
pol_sq = None
|
|
190
|
+
try:
|
|
191
|
+
pol_sq = (spectral.get("policy", {}) or {}).get("sigma_quantile")
|
|
192
|
+
if pol_sq is None:
|
|
193
|
+
# Legacy aliases
|
|
194
|
+
pol_sq = (spectral.get("policy", {}) or {}).get("contraction") or (
|
|
195
|
+
spectral.get("policy", {}) or {}
|
|
196
|
+
).get("kappa")
|
|
197
|
+
except Exception:
|
|
198
|
+
pol_sq = None
|
|
199
|
+
spectral_resolved["sigma_quantile"] = _safe_float(
|
|
200
|
+
pol_sq
|
|
201
|
+
if pol_sq is not None
|
|
202
|
+
else spectral.get(
|
|
203
|
+
"sigma_quantile", spectral_resolved.get("sigma_quantile", 0.95)
|
|
204
|
+
),
|
|
205
|
+
0.95,
|
|
206
|
+
)
|
|
207
|
+
spectral_resolved["deadband"] = _safe_float(
|
|
208
|
+
spectral.get("deadband", spectral_resolved.get("deadband", 0.1)), 0.1
|
|
209
|
+
)
|
|
210
|
+
max_caps_val = spectral.get("max_caps", spectral_resolved.get("max_caps", 5))
|
|
211
|
+
spectral_resolved["max_caps"] = _safe_int(
|
|
212
|
+
max_caps_val, base_spectral.get("max_caps", 5) or 5
|
|
213
|
+
)
|
|
214
|
+
if "ignore_preview_inflation" in base_spectral:
|
|
215
|
+
spectral_resolved["ignore_preview_inflation"] = base_spectral[
|
|
216
|
+
"ignore_preview_inflation"
|
|
217
|
+
]
|
|
218
|
+
spectral_resolved["scope"] = (
|
|
219
|
+
spectral.get("policy", {}).get("scope")
|
|
220
|
+
or spectral_resolved.get("scope")
|
|
221
|
+
or "all"
|
|
222
|
+
)
|
|
223
|
+
mt_source = spectral.get("multiple_testing") or spectral_resolved.get(
|
|
224
|
+
"multiple_testing"
|
|
225
|
+
)
|
|
226
|
+
if isinstance(mt_source, dict):
|
|
227
|
+
mt_entry = {
|
|
228
|
+
"method": mt_source.get("method"),
|
|
229
|
+
"alpha": _safe_float(mt_source.get("alpha", 0.05), 0.05),
|
|
230
|
+
}
|
|
231
|
+
m_val = mt_source.get("m")
|
|
232
|
+
mt_entry["m"] = _safe_int(m_val, len(spectral_resolved["family_caps"] or {}))
|
|
233
|
+
spectral_resolved["multiple_testing"] = mt_entry
|
|
234
|
+
correction_flag = spectral.get("policy", {}).get(
|
|
235
|
+
"correction_enabled",
|
|
236
|
+
spectral_resolved.get("correction_enabled", False),
|
|
237
|
+
)
|
|
238
|
+
spectral_resolved["correction_enabled"] = bool(correction_flag)
|
|
239
|
+
if tier_key == "balanced":
|
|
240
|
+
spectral_resolved["correction_enabled"] = False
|
|
241
|
+
spectral_resolved["max_spectral_norm"] = None
|
|
242
|
+
else:
|
|
243
|
+
spectral_resolved["max_spectral_norm"] = spectral.get("policy", {}).get(
|
|
244
|
+
"max_spectral_norm", spectral_resolved.get("max_spectral_norm")
|
|
245
|
+
)
|
|
246
|
+
resolved["spectral"] = spectral_resolved
|
|
247
|
+
|
|
248
|
+
# RMT guard
|
|
249
|
+
base_rmt = copy.deepcopy(base.get("rmt", {})) if isinstance(base, dict) else {}
|
|
250
|
+
rmt_resolved: dict[str, Any] = {}
|
|
251
|
+
if isinstance(base_rmt, dict):
|
|
252
|
+
rmt_resolved.update(base_rmt)
|
|
253
|
+
rmt_resolved["margin"] = _safe_float(
|
|
254
|
+
rmt.get("margin", rmt_resolved.get("margin", 1.5)), 1.5
|
|
255
|
+
)
|
|
256
|
+
rmt_resolved["deadband"] = _safe_float(
|
|
257
|
+
rmt.get("deadband", rmt_resolved.get("deadband", 0.1)), 0.1
|
|
258
|
+
)
|
|
259
|
+
epsilon_default_val = rmt.get(
|
|
260
|
+
"epsilon_default", rmt_resolved.get("epsilon_default", 0.1)
|
|
261
|
+
)
|
|
262
|
+
rmt_resolved["epsilon_default"] = _safe_float(epsilon_default_val, 0.1)
|
|
263
|
+
from .policy_utils import _format_epsilon_map as _fem
|
|
264
|
+
|
|
265
|
+
epsilon_map = _fem(rmt.get("epsilon_by_family") or rmt_resolved.pop("epsilon", {}))
|
|
266
|
+
if epsilon_map:
|
|
267
|
+
rmt_resolved["epsilon_by_family"] = epsilon_map
|
|
268
|
+
else:
|
|
269
|
+
rmt_resolved.pop("epsilon", None)
|
|
270
|
+
if "epsilon" in rmt_resolved:
|
|
271
|
+
rmt_resolved.pop("epsilon", None)
|
|
272
|
+
if "correct" in rmt_resolved:
|
|
273
|
+
rmt_resolved["correct"] = bool(rmt_resolved["correct"])
|
|
274
|
+
resolved["rmt"] = rmt_resolved
|
|
275
|
+
|
|
276
|
+
# Variance guard
|
|
277
|
+
base_variance = (
|
|
278
|
+
copy.deepcopy(base.get("variance", {})) if isinstance(base, dict) else {}
|
|
279
|
+
)
|
|
280
|
+
variance_resolved: dict[str, Any] = {}
|
|
281
|
+
if isinstance(base_variance, dict):
|
|
282
|
+
variance_resolved.update(base_variance)
|
|
283
|
+
predictive_gate = variance.get("predictive_gate", {})
|
|
284
|
+
predictive_one_sided = variance_resolved.get("predictive_one_sided")
|
|
285
|
+
if isinstance(predictive_gate, dict) and "sided" in predictive_gate:
|
|
286
|
+
predictive_one_sided = predictive_gate.get("sided") in (True, "one_sided")
|
|
287
|
+
variance_resolved["predictive_one_sided"] = bool(
|
|
288
|
+
predictive_one_sided if predictive_one_sided is not None else True
|
|
289
|
+
)
|
|
290
|
+
variance_resolved["min_effect_lognll"] = _safe_float(
|
|
291
|
+
variance_resolved.get("min_effect_lognll", 0.0), 0.0
|
|
292
|
+
)
|
|
293
|
+
variance_resolved["max_adjusted_modules"] = _safe_int(
|
|
294
|
+
variance_resolved.get("max_adjusted_modules", 0), 0
|
|
295
|
+
)
|
|
296
|
+
if "deadband" in variance_resolved:
|
|
297
|
+
variance_resolved["deadband"] = _safe_float(
|
|
298
|
+
variance_resolved.get("deadband", 0.0), 0.0
|
|
299
|
+
)
|
|
300
|
+
if "min_abs_adjust" in variance_resolved:
|
|
301
|
+
variance_resolved["min_abs_adjust"] = _safe_float(
|
|
302
|
+
variance_resolved.get("min_abs_adjust", 0.0), 0.0
|
|
303
|
+
)
|
|
304
|
+
if "max_scale_step" in variance_resolved:
|
|
305
|
+
variance_resolved["max_scale_step"] = _safe_float(
|
|
306
|
+
variance_resolved.get("max_scale_step", 0.0), 0.0
|
|
307
|
+
)
|
|
308
|
+
resolved["variance"] = variance_resolved
|
|
309
|
+
|
|
310
|
+
# Confidence thresholds (optional policy knobs)
|
|
311
|
+
try:
|
|
312
|
+
metrics = base.get("metrics", {}) if isinstance(base, dict) else {}
|
|
313
|
+
conf = metrics.get("confidence") if isinstance(metrics, dict) else None
|
|
314
|
+
if isinstance(conf, dict) and conf:
|
|
315
|
+
resolved["confidence"] = {}
|
|
316
|
+
if "ppl_ratio_width_max" in conf:
|
|
317
|
+
try:
|
|
318
|
+
resolved["confidence"]["ppl_ratio_width_max"] = float(
|
|
319
|
+
conf.get("ppl_ratio_width_max")
|
|
320
|
+
)
|
|
321
|
+
except Exception:
|
|
322
|
+
pass
|
|
323
|
+
if "accuracy_delta_pp_width_max" in conf:
|
|
324
|
+
try:
|
|
325
|
+
resolved["confidence"]["accuracy_delta_pp_width_max"] = float(
|
|
326
|
+
conf.get("accuracy_delta_pp_width_max")
|
|
327
|
+
)
|
|
328
|
+
except Exception:
|
|
329
|
+
pass
|
|
330
|
+
except Exception:
|
|
331
|
+
pass
|
|
332
|
+
|
|
333
|
+
return resolved
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def _extract_effective_policies(report: RunReport) -> dict[str, Any]:
|
|
337
|
+
"""Extract the effective policies that were applied during the run."""
|
|
338
|
+
policies: dict[str, Any] = {}
|
|
339
|
+
|
|
340
|
+
guard_entries: list[dict[str, Any]] = report.get("guards", [])
|
|
341
|
+
for guard in guard_entries:
|
|
342
|
+
guard_name = guard.get("name", "").lower()
|
|
343
|
+
guard_policy = guard.get("policy", {})
|
|
344
|
+
original_policy = dict(guard_policy) if isinstance(guard_policy, dict) else {}
|
|
345
|
+
guard_metrics = guard.get("metrics", {})
|
|
346
|
+
|
|
347
|
+
if not guard_policy and guard_metrics:
|
|
348
|
+
if guard_name == "rmt":
|
|
349
|
+
guard_policy = {
|
|
350
|
+
"deadband": guard_metrics.get("deadband_used", 0.1),
|
|
351
|
+
"margin": guard_metrics.get("margin_used", 1.5),
|
|
352
|
+
"detection_threshold": guard_metrics.get(
|
|
353
|
+
"detection_threshold", 1.65
|
|
354
|
+
),
|
|
355
|
+
"q_method": guard_metrics.get("q_used", "auto"),
|
|
356
|
+
"epsilon_default": guard_metrics.get("epsilon_default"),
|
|
357
|
+
"epsilon_by_family": guard_metrics.get("epsilon_by_family"),
|
|
358
|
+
}
|
|
359
|
+
elif guard_name == "spectral":
|
|
360
|
+
sigma_quantile = guard_metrics.get(
|
|
361
|
+
"sigma_quantile",
|
|
362
|
+
guard_metrics.get("contraction", guard_metrics.get("kappa", 0.95)),
|
|
363
|
+
)
|
|
364
|
+
multiple_testing = guard_metrics.get("multiple_testing") or (
|
|
365
|
+
guard_metrics.get("multipletesting")
|
|
366
|
+
if isinstance(guard_metrics.get("multipletesting"), dict)
|
|
367
|
+
else None
|
|
368
|
+
)
|
|
369
|
+
guard_policy = {
|
|
370
|
+
"max_spectral_norm": guard_metrics.get("max_spectral_norm"),
|
|
371
|
+
"stability_score": guard_metrics.get("stability_score", 0.95),
|
|
372
|
+
"caps_applied": guard_metrics.get("caps_applied", 0),
|
|
373
|
+
"sigma_quantile": sigma_quantile,
|
|
374
|
+
"deadband": guard_metrics.get("deadband", 0.1),
|
|
375
|
+
"max_caps": guard_metrics.get("max_caps", 5),
|
|
376
|
+
}
|
|
377
|
+
if isinstance(multiple_testing, dict) and multiple_testing:
|
|
378
|
+
guard_policy["multiple_testing"] = multiple_testing
|
|
379
|
+
elif guard_name == "variance":
|
|
380
|
+
guard_policy = {
|
|
381
|
+
"scope": guard_metrics.get("scope", "both"),
|
|
382
|
+
"min_gain_threshold": guard_metrics.get("min_gain_threshold", 0.3),
|
|
383
|
+
"target_modules": guard_metrics.get("target_modules", 0),
|
|
384
|
+
"ve_enabled": guard_metrics.get("ve_enabled", False),
|
|
385
|
+
}
|
|
386
|
+
elif guard_name == "invariants":
|
|
387
|
+
guard_policy = {
|
|
388
|
+
"checks_performed": guard_metrics.get("checks_performed", 0),
|
|
389
|
+
"violations_found": guard_metrics.get("violations_found", 0),
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if guard_policy:
|
|
393
|
+
if guard_name == "spectral":
|
|
394
|
+
sigma_quantile = guard_policy.get("sigma_quantile")
|
|
395
|
+
if sigma_quantile is None:
|
|
396
|
+
sigma_quantile = guard_policy.get("contraction")
|
|
397
|
+
if sigma_quantile is None and "kappa" in guard_policy:
|
|
398
|
+
sigma_quantile = guard_policy["kappa"]
|
|
399
|
+
sanitized_policy = dict(guard_policy)
|
|
400
|
+
if sigma_quantile is not None:
|
|
401
|
+
try:
|
|
402
|
+
sanitized_policy["sigma_quantile"] = float(sigma_quantile)
|
|
403
|
+
except (TypeError, ValueError):
|
|
404
|
+
pass
|
|
405
|
+
_promote_legacy_multiple_testing_key(sanitized_policy)
|
|
406
|
+
sanitized_policy.pop("contraction", None)
|
|
407
|
+
sanitized_policy.pop("kappa", None)
|
|
408
|
+
if sanitized_policy.get("max_spectral_norm") in (None, 0):
|
|
409
|
+
sanitized_policy["max_spectral_norm"] = None
|
|
410
|
+
guard_policy = sanitized_policy
|
|
411
|
+
elif guard_name == "rmt" and isinstance(guard_metrics, dict):
|
|
412
|
+
eps_default = guard_metrics.get("epsilon_default")
|
|
413
|
+
if eps_default is not None and "epsilon_default" not in guard_policy:
|
|
414
|
+
guard_policy = dict(guard_policy)
|
|
415
|
+
guard_policy["epsilon_default"] = eps_default
|
|
416
|
+
elif guard_name == "variance" and original_policy:
|
|
417
|
+
guard_policy = dict(guard_policy)
|
|
418
|
+
for key in (
|
|
419
|
+
"deadband",
|
|
420
|
+
"min_abs_adjust",
|
|
421
|
+
"max_scale_step",
|
|
422
|
+
"min_effect_lognll",
|
|
423
|
+
"predictive_one_sided",
|
|
424
|
+
"topk_backstop",
|
|
425
|
+
"max_adjusted_modules",
|
|
426
|
+
):
|
|
427
|
+
if key in original_policy and key not in guard_policy:
|
|
428
|
+
guard_policy[key] = original_policy[key]
|
|
429
|
+
policies[guard_name] = dict(guard_policy)
|
|
430
|
+
|
|
431
|
+
tier_defaults = TIER_POLICIES.get(_resolve_policy_tier(report), {})
|
|
432
|
+
|
|
433
|
+
def _merge_defaults(target: dict[str, Any], defaults: dict[str, Any]) -> None:
|
|
434
|
+
for key, value in defaults.items():
|
|
435
|
+
if isinstance(value, dict):
|
|
436
|
+
target_value = target.get(key)
|
|
437
|
+
if not isinstance(target_value, dict):
|
|
438
|
+
target[key] = copy.deepcopy(value)
|
|
439
|
+
else:
|
|
440
|
+
_merge_defaults(target_value, value)
|
|
441
|
+
else:
|
|
442
|
+
if target.get(key) in (None, "", [], {}):
|
|
443
|
+
target[key] = copy.deepcopy(value)
|
|
444
|
+
|
|
445
|
+
for guard_name, defaults in tier_defaults.items():
|
|
446
|
+
if not isinstance(defaults, dict):
|
|
447
|
+
continue
|
|
448
|
+
if guard_name not in policies:
|
|
449
|
+
policies[guard_name] = copy.deepcopy(defaults)
|
|
450
|
+
else:
|
|
451
|
+
_merge_defaults(policies[guard_name], defaults)
|
|
452
|
+
|
|
453
|
+
if not policies:
|
|
454
|
+
metrics = report.get("metrics", {}) if isinstance(report, dict) else {}
|
|
455
|
+
if "spectral" in metrics:
|
|
456
|
+
policies["spectral"] = {"status": "default_config"}
|
|
457
|
+
if "rmt" in metrics:
|
|
458
|
+
policies["rmt"] = {"status": "default_config"}
|
|
459
|
+
|
|
460
|
+
return policies
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
def _normalize_override_entry(value: Any) -> list[str]:
|
|
464
|
+
if value is None:
|
|
465
|
+
return []
|
|
466
|
+
if isinstance(value, str):
|
|
467
|
+
return [value]
|
|
468
|
+
if isinstance(value, list | tuple | set):
|
|
469
|
+
return [str(item) for item in value if item is not None]
|
|
470
|
+
return []
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
def _extract_policy_overrides(report: RunReport) -> list[str]:
|
|
474
|
+
"""Return ordered list of policy override paths referenced by the run."""
|
|
475
|
+
overrides: list[str] = []
|
|
476
|
+
meta = report.get("meta", {})
|
|
477
|
+
config = report.get("config", {})
|
|
478
|
+
candidate_sources: list[str] = []
|
|
479
|
+
if isinstance(meta, dict):
|
|
480
|
+
candidate_sources.extend(
|
|
481
|
+
_normalize_override_entry(meta.get("policy_overrides"))
|
|
482
|
+
)
|
|
483
|
+
candidate_sources.extend(_normalize_override_entry(meta.get("overrides")))
|
|
484
|
+
auto_meta = meta.get("auto")
|
|
485
|
+
if isinstance(auto_meta, dict):
|
|
486
|
+
candidate_sources.extend(
|
|
487
|
+
_normalize_override_entry(auto_meta.get("overrides"))
|
|
488
|
+
)
|
|
489
|
+
if isinstance(config, dict):
|
|
490
|
+
candidate_sources.extend(_normalize_override_entry(config.get("overrides")))
|
|
491
|
+
seen: set[str] = set()
|
|
492
|
+
for entry in candidate_sources:
|
|
493
|
+
if entry and entry not in seen:
|
|
494
|
+
overrides.append(entry)
|
|
495
|
+
seen.add(entry)
|
|
496
|
+
return overrides
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
def _compute_policy_digest(policy: dict[str, Any]) -> str:
|
|
500
|
+
canonical = json.dumps(policy, sort_keys=True, default=str)
|
|
501
|
+
return hashlib.sha256(canonical.encode()).hexdigest()[:16]
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
__all__ = [
|
|
505
|
+
"_compute_variance_policy_digest",
|
|
506
|
+
"_compute_thresholds_payload",
|
|
507
|
+
"_compute_thresholds_hash",
|
|
508
|
+
"_promote_legacy_multiple_testing_key",
|
|
509
|
+
"_resolve_policy_tier",
|
|
510
|
+
"_build_resolved_policies",
|
|
511
|
+
"_extract_effective_policies",
|
|
512
|
+
"_normalize_override_entry",
|
|
513
|
+
"_extract_policy_overrides",
|
|
514
|
+
"_format_family_caps",
|
|
515
|
+
"_format_epsilon_map",
|
|
516
|
+
"_compute_policy_digest",
|
|
517
|
+
]
|