mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-17 03:59:28 +00:00
learn/compile.toml: the pre-registered spec -- balanced Brier score of the raw score on C_val (cells by family x label, repositories capped at 5, unsure = 0.5, ties within 0.005 to fewer prompt tokens), seed, the compile split (25%, boot 60/40, compile-split-only memory), bootstrap (150 candidates, confidence >= 0.7, 4 sets of 3), search (6 proposals + baseline, 20 errors shown, 60 validation candidates), k = 1, the retrieval settings, and the $3 / 1,200-call ceiling. learn/compile.py: bootstrap few-shot keeps only right, confident rationales that cite a line and name no repository, path or CVE/GHSA id; seeded demo sets (positive, negative, any; families mixed) with other-framework alternates; one proposal call; 7 instructions scored with set 1, the best with sets 2-4. The artifact is canonical JSON stored as programs/<program_id>.json, program_id = sha256 of the artifact without its id; it records the spec sha, memory/compile-groups/folds digests and the response-cache digest, with spend priced from cached usage, so a rerun from the cache is byte-identical at $0 (tested on FileStore and MinioStore through the fake client; real MinIO gated as today). A ceiling ends the compile `unfinished` with no artifact. packageable() keeps only permissively licensed demonstrations (MIT, BSD, Apache-2.0, ISC, zlib), swapping in a permissive alternate or dropping, under a new program id. learn/calibrate.py: Platt scaling on logit(s), pure Python Newton, per family / pooled with family intercepts / insufficient data by the floors; cross-fitted (fold j's map is fitted on the other folds only); the check (5-bin reliability, slope and intercept with repository-bootstrap CIs, ECE <= 0.05), ADVISORY only when it fails. learn/evaluate.py: predictions under each fold's boundary, families below the floor never asked; operating points read from the calibrated, cross-fitted predictions of the other folds (BLOCK: Wilson lower bound >= 0.95, never on a majority unsure; ADVISORY: recall >= 0.90); repository-cluster bootstrap intervals; strata with "insufficient data"; >5% parse failures is an instrument failure; explanations keep only signals the record holds; version mismatch names the fallback reason; the memory-size learning curve. `ousast learn compile|evaluate|curve`: paid runs need --budget-usd (exit 3 at the ceiling), --replay-only runs from the cache. Nothing was spent: every test and the dry run used scripted clients. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
231 lines
9.9 KiB
Python
231 lines
9.9 KiB
Python
"""Calibration of the program's score on held-out repositories (learned-decision-engine design 4.4, Req 3.5, 7.4).
|
|
|
|
Pure Python, no fitted classifier: the raw score ``s`` (the vote mean) is mapped by **Platt scaling** on
|
|
``logit(clip(s, 0.01, 0.99))``, a two-parameter logistic fitted by Newton's method with Platt's smoothed targets.
|
|
|
|
- **Cross-fitted**: the map applied to fold j is fitted on the out-of-fold predictions of the other folds only
|
|
(:func:`cross_fit`), so no map is checked on the fold it was fitted on.
|
|
- Per family when the family reaches the per-family floor of positive and negative repository groups; pooled with
|
|
a per-family intercept between the floors; otherwise ``insufficient data`` (no calibrated probability).
|
|
- **The check** (:func:`check`): a reliability table (5 quantile bins), the calibration slope and intercept (a
|
|
logistic regression of the label on ``logit(p)``) with repository-bootstrap 95% intervals, and the expected
|
|
calibration error. It holds when the slope interval contains 1, the intercept interval contains 0 and ECE <= 0.05;
|
|
otherwise only ADVISORY is offered (``block.offered = false, reason = "calibration"``).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import math
|
|
import random
|
|
from collections.abc import Mapping, Sequence
|
|
from dataclasses import dataclass, field
|
|
from typing import Any
|
|
|
|
from .labels import PER_FAMILY_FLOOR, POOLED_FLOOR
|
|
|
|
CLIP = 0.01
|
|
ECE_LIMIT = 0.05
|
|
BINS = 5
|
|
|
|
|
|
def logit(p: float) -> float:
|
|
q = min(max(p, CLIP), 1 - CLIP)
|
|
return math.log(q / (1 - q))
|
|
|
|
|
|
def sigmoid(z: float) -> float:
|
|
if z >= 0:
|
|
return 1 / (1 + math.exp(-z))
|
|
e = math.exp(z)
|
|
return e / (1 + e)
|
|
|
|
|
|
def _solve(a: list[list[float]], b: list[float]) -> list[float]:
|
|
"""Gaussian elimination with partial pivoting (the systems here are 2 to ~10 wide)."""
|
|
n = len(b)
|
|
m = [row[:] + [b[i]] for i, row in enumerate(a)]
|
|
for col in range(n):
|
|
pivot = max(range(col, n), key=lambda r: abs(m[r][col]))
|
|
m[col], m[pivot] = m[pivot], m[col]
|
|
if abs(m[col][col]) < 1e-12:
|
|
continue
|
|
for r in range(n):
|
|
if r != col:
|
|
f = m[r][col] / m[col][col]
|
|
for c in range(col, n + 1):
|
|
m[r][c] -= f * m[col][c]
|
|
return [m[i][n] / m[i][i] if abs(m[i][i]) >= 1e-12 else 0.0 for i in range(n)]
|
|
|
|
|
|
def fit_logistic(xs: Sequence[Sequence[float]], ys: Sequence[float], *, l2: float = 1e-3, iterations: int = 100) -> list[float]:
|
|
"""Weights of ``y ~ sigmoid(w . x)`` by Newton's method with a small ridge (separable data stays finite)."""
|
|
d = len(xs[0]) if xs else 0
|
|
w = [0.0] * d
|
|
for _ in range(iterations):
|
|
grad = [-l2 * wi for wi in w]
|
|
hess = [[(l2 if i == j else 0.0) for j in range(d)] for i in range(d)]
|
|
for x, y in zip(xs, ys, strict=True):
|
|
p = sigmoid(sum(wi * xi for wi, xi in zip(w, x, strict=True)))
|
|
for i in range(d):
|
|
grad[i] += (y - p) * x[i]
|
|
for j in range(d):
|
|
hess[i][j] += p * (1 - p) * x[i] * x[j]
|
|
step = _solve(hess, grad)
|
|
w = [wi + si for wi, si in zip(w, step, strict=True)]
|
|
if max((abs(s) for s in step), default=0.0) < 1e-9:
|
|
break
|
|
return w
|
|
|
|
|
|
def platt_targets(ys: Sequence[int]) -> list[float]:
|
|
pos = sum(1 for y in ys if y == 1)
|
|
neg = len(ys) - pos
|
|
hi, lo = (pos + 1) / (pos + 2), 1 / (neg + 2)
|
|
return [hi if y == 1 else lo for y in ys]
|
|
|
|
|
|
def fit_platt(scores: Sequence[float], labels: Sequence[int]) -> tuple[float, float]:
|
|
"""(a, b) of ``p = sigmoid(a logit(s) + b)``."""
|
|
a, b = fit_logistic([[logit(s), 1.0] for s in scores], platt_targets(labels))
|
|
return a, b
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Row:
|
|
"""One out-of-fold prediction: its fold, family, repository group, label and raw score."""
|
|
|
|
fold: str
|
|
family: str
|
|
group: str
|
|
label: int
|
|
s: float
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class CalibrationMap:
|
|
per_family: Mapping[str, tuple[float, float]] = field(default_factory=dict)
|
|
pooled: tuple[float, float] | None = None # slope and baseline intercept of the pooled map
|
|
intercepts: Mapping[str, float] = field(default_factory=dict) # per-family intercept shift of the pooled map
|
|
insufficient: tuple[str, ...] = ()
|
|
|
|
def apply(self, family: str, s: float) -> float | None:
|
|
if family in self.per_family:
|
|
a, b = self.per_family[family]
|
|
return sigmoid(a * logit(s) + b)
|
|
if self.pooled is not None and family in self.intercepts:
|
|
a, b = self.pooled
|
|
return sigmoid(a * logit(s) + b + self.intercepts[family])
|
|
return None
|
|
|
|
def as_dict(self) -> dict[str, Any]:
|
|
return {
|
|
"per_family": {f: list(v) for f, v in sorted(self.per_family.items())}, "pooled": list(self.pooled) if self.pooled else None,
|
|
"intercepts": dict(sorted(self.intercepts.items())), "insufficient": list(self.insufficient),
|
|
} # fmt: skip
|
|
|
|
|
|
def _groups(rows: Sequence[Row], family: str, label: int) -> int:
|
|
return len({r.group for r in rows if r.family == family and r.label == label})
|
|
|
|
|
|
def fit_map(rows: Sequence[Row], *, per_family_floor: int = PER_FAMILY_FLOOR, pooled_floor: int = POOLED_FLOOR) -> CalibrationMap:
|
|
families = sorted({r.family for r in rows})
|
|
level = {f: min(_groups(rows, f, 1), _groups(rows, f, 0)) for f in families}
|
|
own = [f for f in families if level[f] >= per_family_floor]
|
|
pooled = [f for f in families if pooled_floor <= level[f] < per_family_floor]
|
|
per_family = {f: fit_platt([r.s for r in rows if r.family == f], [r.label for r in rows if r.family == f]) for f in own}
|
|
pooled_map: tuple[float, float] | None = None
|
|
intercepts: dict[str, float] = {}
|
|
if pooled:
|
|
chosen = [r for r in rows if r.family in pooled]
|
|
xs = [[logit(r.s), 1.0] + [1.0 if r.family == f else 0.0 for f in pooled[1:]] for r in chosen]
|
|
w = fit_logistic(xs, platt_targets([r.label for r in chosen]))
|
|
pooled_map = (w[0], w[1])
|
|
intercepts = {f: (w[2 + i - 1] if i else 0.0) for i, f in enumerate(pooled)}
|
|
return CalibrationMap(per_family, pooled_map, intercepts, tuple(f for f in families if level[f] < pooled_floor))
|
|
|
|
|
|
def cross_fit(rows: Sequence[Row], **floors: int) -> tuple[list[float | None], dict[str, CalibrationMap]]:
|
|
"""Calibrated ``p`` per row, each from a map fitted on the other folds' rows only; and the map per fold."""
|
|
maps = {fold: fit_map([r for r in rows if r.fold != fold], **floors) for fold in sorted({r.fold for r in rows})}
|
|
return [maps[r.fold].apply(r.family, r.s) for r in rows], maps
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Check:
|
|
reliability: tuple[Mapping[str, float], ...]
|
|
slope: float
|
|
slope_ci: tuple[float, float]
|
|
intercept: float
|
|
intercept_ci: tuple[float, float]
|
|
ece: float
|
|
holds: bool
|
|
n: int
|
|
|
|
def as_dict(self) -> dict[str, Any]:
|
|
return {
|
|
"reliability": [dict(b) for b in self.reliability], "slope": round(self.slope, 4),
|
|
"slope_ci": [round(v, 4) for v in self.slope_ci], "intercept": round(self.intercept, 4),
|
|
"intercept_ci": [round(v, 4) for v in self.intercept_ci], "ece": round(self.ece, 4), "holds": self.holds, "n": self.n,
|
|
} # fmt: skip
|
|
|
|
|
|
def _slope_intercept(ps: Sequence[float], ys: Sequence[int]) -> tuple[float, float]:
|
|
a, b = fit_logistic([[logit(p), 1.0] for p in ps], [float(y) for y in ys])
|
|
return a, b
|
|
|
|
|
|
def reliability(ps: Sequence[float], ys: Sequence[int], bins: int = BINS) -> tuple[list[dict[str, float]], float]:
|
|
order = sorted(range(len(ps)), key=lambda i: ps[i])
|
|
table, ece = [], 0.0
|
|
for b in range(bins):
|
|
idx = order[b * len(order) // bins : (b + 1) * len(order) // bins]
|
|
if not idx:
|
|
continue
|
|
mean_p = sum(ps[i] for i in idx) / len(idx)
|
|
rate = sum(ys[i] for i in idx) / len(idx)
|
|
table.append({"n": len(idx), "mean_p": round(mean_p, 4), "positive_rate": round(rate, 4)})
|
|
ece += len(idx) / len(ps) * abs(mean_p - rate)
|
|
return table, ece
|
|
|
|
|
|
def _percentile(values: Sequence[float], q: float) -> float:
|
|
ordered = sorted(values)
|
|
return ordered[min(len(ordered) - 1, max(0, round(q * (len(ordered) - 1))))]
|
|
|
|
|
|
def check(ps: Sequence[float], ys: Sequence[int], groups: Sequence[str], *, resamples: int = 200, seed: int = 0) -> Check:
|
|
"""The calibration check on held-out predictions, with repository-cluster bootstrap intervals."""
|
|
table, ece = reliability(ps, ys)
|
|
slope, intercept = _slope_intercept(ps, ys)
|
|
by_group: dict[str, list[int]] = {}
|
|
for i, g in enumerate(groups):
|
|
by_group.setdefault(g, []).append(i)
|
|
names = sorted(by_group)
|
|
rng = random.Random(seed)
|
|
slopes, intercepts = [], []
|
|
for _ in range(resamples):
|
|
idx = [i for g in (rng.choice(names) for _ in names) for i in by_group[g]]
|
|
sample_y = [ys[i] for i in idx]
|
|
if len(set(sample_y)) < 2:
|
|
continue
|
|
a, b = _slope_intercept([ps[i] for i in idx], sample_y)
|
|
slopes.append(a)
|
|
intercepts.append(b)
|
|
slope_ci = (_percentile(slopes, 0.025), _percentile(slopes, 0.975)) if slopes else (math.nan, math.nan)
|
|
intercept_ci = (_percentile(intercepts, 0.025), _percentile(intercepts, 0.975)) if intercepts else (math.nan, math.nan)
|
|
holds = bool(slopes) and slope_ci[0] <= 1 <= slope_ci[1] and intercept_ci[0] <= 0 <= intercept_ci[1] and ece <= ECE_LIMIT
|
|
return Check(tuple(table), slope, slope_ci, intercept, intercept_ci, ece, holds, len(ps))
|
|
|
|
|
|
def offered(result: Check) -> dict[str, dict[str, Any]]:
|
|
"""What a family is offered: ADVISORY always; BLOCK only when calibration holds."""
|
|
block = {"offered": True, "reason": None} if result.holds else {"offered": False, "reason": "calibration"}
|
|
return {"block": block, "advisory": {"offered": True, "reason": None}}
|
|
|
|
|
|
__all__ = [
|
|
"ECE_LIMIT", "CalibrationMap", "Check", "Row", "check", "cross_fit", "fit_logistic", "fit_map", "fit_platt", "logit", "offered",
|
|
"reliability", "sigmoid",
|
|
] # fmt: skip
|