| 1 | """Quiet-host calibration for the scale lane: evidence verified by recomputation.
|
| 2 |
|
| 3 | A scale row's ``claim_eligible`` / ``evidence_class`` are DERIVED, never a
|
| 4 | free flag, and nothing a calibration record *states* is trusted:
|
| 5 |
|
| 6 | 1. ``run_scale_suite.py calibrate`` runs an identical-binary A/A campaign
|
| 7 | (git, git_aa, oak_installed, oak_installed_aa) plus host probes (load
|
| 8 | average, small-file creation rate, F_FULLFSYNC latency) and writes its rows
|
| 9 | to a JSONL file. The record names that file's content sha256.
|
| 10 | 2. Publishing requires that calibration JSONL among publish_gate's inputs,
|
| 11 | matched by content sha256. The gate RECOMPUTES the A/A cell count, per-cell
|
| 12 | floors (oakbench.cellstats, the P1 machinery), identical-binary false
|
| 13 | claims, host load and disk probes from those rows, and checks that the
|
| 14 | calibration rows and the published rows share runner identity, host
|
| 15 | cpu_count and physical memory, the Oak and Git binary sha256, and
|
| 16 | registry-pinned fixtures. The published run must carry its own quiet disk
|
| 17 | probes too.
|
| 18 |
|
| 19 | This detects edited, resealed, copied or invented records (the sealed digest
|
| 20 | is only an integrity check of the record's own content). It cannot detect a
|
| 21 | fabricated calibration JSONL with invented timings; that would need a signed
|
| 22 | runner, which the lane does not have. Do not describe it as forgery-proof.
|
| 23 | """
|
| 24 |
|
| 25 | from __future__ import annotations
|
| 26 |
|
| 27 | import hashlib
|
| 28 | import json
|
| 29 | import os
|
| 30 | import statistics
|
| 31 | import time
|
| 32 | from pathlib import Path
|
| 33 | from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple
|
| 34 |
|
| 35 | SCHEMA_VERSION = 2
|
| 36 | KIND = "oakbench_quiet_host_calibration"
|
| 37 | CALIBRATED_EVIDENCE_CLASS = "calibrated_quiet_host"
|
| 38 | DEVELOPMENT_EVIDENCE_CLASS = "development_only_loaded_host"
|
| 39 | POLICY_VERSION = "2026-09-29.2"
|
| 40 | # Quiet-host policy (provisional; re-derive on the dedicated runner and bump
|
| 41 | # POLICY_VERSION). Load/core 0.1 is ~1.4 runnable threads on a 14-core host.
|
| 42 | MAX_LOAD_PER_CORE = 0.10
|
| 43 | MIN_AA_CELLS = 20
|
| 44 | MIN_RUNS = 5
|
| 45 | MAX_AA_FLOOR_MEDIAN_PCT = 10.0
|
| 46 | # Disk contention (load average does not see it; Oak clone/switch are
|
| 47 | # fsync-bound, fb-549). Measured on the loaded dev host: F_FULLFSYNC median
|
| 48 | # 3.7 ms, file creation as low as 170 files/s.
|
| 49 | MAX_FULLFSYNC_MEDIAN_MS = 2.5
|
| 50 | MIN_CREATE_FILES_PER_S = 2000.0
|
| 51 | PROBE_OPERATIONS = ("host.disk_fullfsync", "host.file_create_rate")
|
| 52 | AA_PAIRS = (("git", "git_aa"), ("oak_installed", "oak_installed_aa"))
|
| 53 |
|
| 54 |
|
| 55 | # ---------------------------------------------------------------------------
|
| 56 | # Host facts and probes
|
| 57 | # ---------------------------------------------------------------------------
|
| 58 |
|
| 59 |
|
| 60 | def host_facts() -> Dict[str, Any]:
|
| 61 | try:
|
| 62 | mem = int(os.sysconf("SC_PAGE_SIZE")) * int(os.sysconf("SC_PHYS_PAGES"))
|
| 63 | except (ValueError, OSError, AttributeError):
|
| 64 | mem = None
|
| 65 | return {"host_cpu_count": os.cpu_count(), "host_mem_bytes": mem}
|
| 66 |
|
| 67 |
|
| 68 | def disk_probe(directory: Path, samples: int = 20, files: int = 500) -> Dict[str, Any]:
|
| 69 | """F_FULLFSYNC (fsync elsewhere) latency of a 4 KiB write, and small-file creation rate."""
|
| 70 | import fcntl
|
| 71 | directory = Path(directory)
|
| 72 | directory.mkdir(parents=True, exist_ok=True)
|
| 73 | full = getattr(fcntl, "F_FULLFSYNC", None)
|
| 74 | latencies = []
|
| 75 | path = directory / ".oakbench-fsync-probe"
|
| 76 | for _ in range(samples):
|
| 77 | fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
|
| 78 | try:
|
| 79 | os.write(fd, os.urandom(4096))
|
| 80 | start = time.perf_counter()
|
| 81 | if full is not None:
|
| 82 | fcntl.fcntl(fd, full)
|
| 83 | else:
|
| 84 | os.fsync(fd)
|
| 85 | latencies.append((time.perf_counter() - start) * 1000.0)
|
| 86 | finally:
|
| 87 | os.close(fd)
|
| 88 | path.unlink()
|
| 89 | tree = directory / ".oakbench-create-probe"
|
| 90 | tree.mkdir(exist_ok=True)
|
| 91 | start = time.perf_counter()
|
| 92 | for index in range(files):
|
| 93 | with open(tree / f"f{index}", "wb") as handle:
|
| 94 | handle.write(b"x" * 64)
|
| 95 | elapsed = time.perf_counter() - start
|
| 96 | for index in range(files):
|
| 97 | (tree / f"f{index}").unlink()
|
| 98 | tree.rmdir()
|
| 99 | return {"fullfsync_ms": [round(v, 4) for v in latencies],
|
| 100 | "fullfsync_kind": "F_FULLFSYNC" if full is not None else "fsync",
|
| 101 | "create_files": files, "create_elapsed_s": round(elapsed, 6)}
|
| 102 |
|
| 103 |
|
| 104 | def probe_rows(probe: Dict[str, Any], base: Dict[str, Any], phase: str) -> List[Dict[str, Any]]:
|
| 105 | """Diagnostic rows carrying probe samples (so the gate can recompute them)."""
|
| 106 | common = {**base, "subject": "harness", "subject_kind": "harness", "command": [], "returncode": 0,
|
| 107 | "diagnostic": True, "probe_phase": phase, "measurement_source": "harness_phase_wall_clock",
|
| 108 | "evidence_class": DEVELOPMENT_EVIDENCE_CLASS, "claim_eligible": False,
|
| 109 | "claim_ineligible_reasons": ["host probe (diagnostic)"], **host_facts()}
|
| 110 | rows = [dict(common, operation="host.disk_fullfsync", run=index, elapsed_ms=value,
|
| 111 | fsync_kind=probe["fullfsync_kind"]) for index, value in enumerate(probe["fullfsync_ms"])]
|
| 112 | rate = probe["create_files"] / probe["create_elapsed_s"] if probe["create_elapsed_s"] > 0 else 0.0
|
| 113 | rows.append(dict(common, operation="host.file_create_rate", run=0,
|
| 114 | elapsed_ms=round(probe["create_elapsed_s"] * 1000.0, 3), files=probe["create_files"],
|
| 115 | files_per_s=round(rate, 1)))
|
| 116 | return rows
|
| 117 |
|
| 118 |
|
| 119 | def probe_verdict(rows: Iterable[Dict[str, Any]]) -> Tuple[List[str], Dict[str, Any]]:
|
| 120 | rows = list(rows)
|
| 121 | fsyncs = [r["elapsed_ms"] for r in rows if r.get("operation") == "host.disk_fullfsync"
|
| 122 | and isinstance(r.get("elapsed_ms"), (int, float))]
|
| 123 | rates = [r.get("files_per_s") for r in rows if r.get("operation") == "host.file_create_rate"]
|
| 124 | reasons, facts = [], {}
|
| 125 | if len(fsyncs) < 10 or not rates:
|
| 126 | return ["disk probes missing"], facts
|
| 127 | facts["fullfsync_median_ms"] = statistics.median(fsyncs)
|
| 128 | facts["create_files_per_s_min"] = min(r for r in rates if isinstance(r, (int, float)))
|
| 129 | if facts["fullfsync_median_ms"] > MAX_FULLFSYNC_MEDIAN_MS:
|
| 130 | reasons.append(f"disk contended: F_FULLFSYNC median {facts['fullfsync_median_ms']:.2f} ms > "
|
| 131 | f"{MAX_FULLFSYNC_MEDIAN_MS} ms")
|
| 132 | if facts["create_files_per_s_min"] < MIN_CREATE_FILES_PER_S:
|
| 133 | reasons.append(f"disk contended: {facts['create_files_per_s_min']:.0f} files/s < {MIN_CREATE_FILES_PER_S:.0f}")
|
| 134 | return reasons, facts
|
| 135 |
|
| 136 |
|
| 137 | # ---------------------------------------------------------------------------
|
| 138 | # Records
|
| 139 | # ---------------------------------------------------------------------------
|
| 140 |
|
| 141 |
|
| 142 | def file_sha256(path: Path) -> str:
|
| 143 | digest = hashlib.sha256()
|
| 144 | with Path(path).open("rb") as handle:
|
| 145 | for chunk in iter(lambda: handle.read(1 << 20), b""):
|
| 146 | digest.update(chunk)
|
| 147 | return digest.hexdigest()
|
| 148 |
|
| 149 |
|
| 150 | def record_digest(record: Dict[str, Any]) -> str:
|
| 151 | body = {key: value for key, value in record.items() if key != "record_sha256"}
|
| 152 | return hashlib.sha256(json.dumps(body, sort_keys=True, separators=(",", ":")).encode()).hexdigest()
|
| 153 |
|
| 154 |
|
| 155 | def seal(record: Dict[str, Any]) -> Dict[str, Any]:
|
| 156 | sealed = dict(record)
|
| 157 | sealed.update(schema_version=SCHEMA_VERSION, kind=KIND, policy_version=POLICY_VERSION)
|
| 158 | sealed["record_sha256"] = record_digest(sealed)
|
| 159 | return sealed
|
| 160 |
|
| 161 |
|
| 162 | def load_rows(path: Path) -> List[Dict[str, Any]]:
|
| 163 | return [json.loads(line) for line in Path(path).read_text().splitlines() if line.strip()]
|
| 164 |
|
| 165 |
|
| 166 | def _pin_problems(rows: Iterable[Dict[str, Any]], registry: Optional[Dict[str, Any]]) -> List[str]:
|
| 167 | if registry is None:
|
| 168 | return []
|
| 169 | pins = {entry.get("spec_sha256"): entry.get("refs_sha256") for entry in registry.values()
|
| 170 | if isinstance(entry, dict) and entry.get("spec_sha256")}
|
| 171 | bad = set()
|
| 172 | for row in rows:
|
| 173 | if row.get("subject_kind") == "harness" or row.get("diagnostic"):
|
| 174 | continue
|
| 175 | spec, refs = row.get("fixture_spec_sha256"), row.get("fixture_manifest_sha256")
|
| 176 | if not spec or pins.get(spec) is None or pins.get(spec) != refs:
|
| 177 | bad.add(str(row.get("fixture_id")))
|
| 178 | return [f"fixture not registry-pinned or pin mismatch: {sorted(bad)[:3]}"] if bad else []
|
| 179 |
|
| 180 |
|
| 181 | def campaign_identity(rows: Sequence[Dict[str, Any]]) -> Tuple[Dict[str, Any], List[str]]:
|
| 182 | """Runner/host/binary identity shared by every row of a run (or problems)."""
|
| 183 | reasons: List[str] = []
|
| 184 | identity: Dict[str, Any] = {}
|
| 185 | for key in ("runner_id", "host_cpu_count", "host_mem_bytes"):
|
| 186 | values = {row.get(key) for row in rows}
|
| 187 | if len(values) != 1 or None in values:
|
| 188 | reasons.append(f"rows disagree on or lack {key}: {sorted(map(str, values))[:3]}")
|
| 189 | else:
|
| 190 | identity[key] = values.pop()
|
| 191 | for kind in ("git", "oak"):
|
| 192 | shas = {row.get("binary_sha256") for row in rows if row.get("subject_kind") == kind
|
| 193 | and not row.get("diagnostic")}
|
| 194 | shas.discard(None)
|
| 195 | if len(shas) > 1:
|
| 196 | reasons.append(f"{kind} rows name several binaries")
|
| 197 | identity[f"{kind}_binary_sha256"] = shas.pop() if len(shas) == 1 else None
|
| 198 | return identity, reasons
|
| 199 |
|
| 200 |
|
| 201 | def recompute(rows: Sequence[Dict[str, Any]], registry: Optional[Dict[str, Any]] = None
|
| 202 | ) -> Tuple[Dict[str, Any], List[str]]:
|
| 203 | """Recompute every calibration number from the campaign's own rows."""
|
| 204 | from oakbench import cellstats
|
| 205 | identity, reasons = campaign_identity(rows)
|
| 206 | measured = [r for r in rows if r.get("profile") == "scale" and r.get("returncode") == 0
|
| 207 | and not r.get("diagnostic") and isinstance(r.get("elapsed_ms"), (int, float))]
|
| 208 | value = lambda r: r.get("elapsed_ms") # noqa: E731
|
| 209 | floors: List[float] = []
|
| 210 | false_claims = 0
|
| 211 | for arm, control in AA_PAIRS:
|
| 212 | runs = {r.get("run") for r in measured if r.get("subject") == arm}
|
| 213 | if len(runs) < MIN_RUNS:
|
| 214 | reasons.append(f"{arm}: fewer than {MIN_RUNS} runs")
|
| 215 | continue
|
| 216 | cell = cellstats.cell_floors(measured, arm, control, value)
|
| 217 | floors.extend(cell.values())
|
| 218 | verdicts = cellstats.classify_cells(measured, control, arm, cell, value_of=value)
|
| 219 | false_claims += sum(1 for item in verdicts.values() if item.get("verdict") in ("regression", "improvement"))
|
| 220 | cpus = identity.get("host_cpu_count")
|
| 221 | loads = [r["environment_sample"]["loadavg"][0] for r in rows
|
| 222 | if isinstance((r.get("environment_sample") or {}).get("loadavg"), list)]
|
| 223 | load_per_core = max(loads) / cpus if loads and isinstance(cpus, int) and cpus > 0 else None
|
| 224 | disk_reasons, disk = probe_verdict(rows)
|
| 225 | facts = {**identity, "aa_cells": len(floors),
|
| 226 | "aa_floor_median_pct": round(statistics.median(floors), 3) if floors else None,
|
| 227 | "aa_false_claims": false_claims,
|
| 228 | "loadavg_per_core_max": round(load_per_core, 4) if load_per_core is not None else None, **disk}
|
| 229 | if len(floors) < MIN_AA_CELLS:
|
| 230 | reasons.append(f"too few A/A cells ({len(floors)} < {MIN_AA_CELLS})")
|
| 231 | if facts["aa_floor_median_pct"] is None or facts["aa_floor_median_pct"] > MAX_AA_FLOOR_MEDIAN_PCT:
|
| 232 | reasons.append(f"A/A floor median {facts['aa_floor_median_pct']}% > {MAX_AA_FLOOR_MEDIAN_PCT}%")
|
| 233 | if false_claims:
|
| 234 | reasons.append(f"identical-binary A/A produced {false_claims} claim(s)")
|
| 235 | if load_per_core is None or load_per_core > MAX_LOAD_PER_CORE:
|
| 236 | reasons.append(f"host not quiet: load/core {load_per_core} > {MAX_LOAD_PER_CORE}")
|
| 237 | reasons += disk_reasons
|
| 238 | reasons += _pin_problems(rows, registry)
|
| 239 | return facts, reasons
|
| 240 |
|
| 241 |
|
| 242 | def verify_campaign(record: Any, calibration_rows: Optional[Sequence[Dict[str, Any]]],
|
| 243 | calibration_sha256: Optional[str], registry: Optional[Dict[str, Any]] = None
|
| 244 | ) -> Tuple[Dict[str, Any], List[str]]:
|
| 245 | """Validate a record against its recomputed campaign; returns (facts, reasons)."""
|
| 246 | if not isinstance(record, dict):
|
| 247 | return {}, ["calibration record missing or not an object"]
|
| 248 | reasons = []
|
| 249 | if record.get("schema_version") != SCHEMA_VERSION or record.get("kind") != KIND:
|
| 250 | reasons.append("wrong schema_version/kind")
|
| 251 | if record.get("record_sha256") != record_digest(record):
|
| 252 | reasons.append("record_sha256 does not match content (edited record)")
|
| 253 | if calibration_rows is None:
|
| 254 | return {}, reasons + ["calibration campaign rows not provided (need the JSONL named by the record)"]
|
| 255 | if not calibration_sha256 or calibration_sha256 != record.get("calibration_rows_sha256"):
|
| 256 | return {}, reasons + ["calibration JSONL content sha256 does not match the record"]
|
| 257 | facts, problems = recompute(calibration_rows, registry)
|
| 258 | reasons += problems
|
| 259 | for key in ("runner_id", "host_cpu_count", "host_mem_bytes", "oak_binary_sha256", "git_binary_sha256",
|
| 260 | "aa_cells", "aa_false_claims"):
|
| 261 | if record.get(key) != facts.get(key):
|
| 262 | reasons.append(f"record {key} {record.get(key)!r} != recomputed {facts.get(key)!r}")
|
| 263 | return facts, reasons
|
| 264 |
|
| 265 |
|
| 266 | def row_problems(row: Dict[str, Any], facts: Dict[str, Any]) -> List[str]:
|
| 267 | """A published row must come from the calibrated runner, host and binaries, on a quiet host."""
|
| 268 | reasons = []
|
| 269 | for key in ("runner_id", "host_cpu_count", "host_mem_bytes"):
|
| 270 | if row.get(key) != facts.get(key):
|
| 271 | reasons.append(f"row {key} {row.get(key)!r} != calibration {facts.get(key)!r}")
|
| 272 | kind = row.get("subject_kind")
|
| 273 | if kind in ("git", "oak") and row.get("binary_sha256") != facts.get(f"{kind}_binary_sha256"):
|
| 274 | reasons.append(f"row {kind} binary differs from the calibrated binary")
|
| 275 | sample = row.get("environment_sample") or {}
|
| 276 | load = sample.get("loadavg") if isinstance(sample, dict) else None
|
| 277 | cpus = facts.get("host_cpu_count")
|
| 278 | if not isinstance(load, list) or not load or not isinstance(cpus, int) or load[0] / cpus > MAX_LOAD_PER_CORE:
|
| 279 | reasons.append("row host load/core not quiet")
|
| 280 | if row.get("fixture_pin_status") != "verified":
|
| 281 | reasons.append("row fixture not verified against its registry pin")
|
| 282 | if row.get("returncode") != 0:
|
| 283 | reasons.append("row is not a successful measurement")
|
| 284 | return reasons
|
| 285 |
|
| 286 |
|
| 287 | def stamp(row: Dict[str, Any], record: Optional[Dict[str, Any]], facts: Optional[Dict[str, Any]],
|
| 288 | campaign_reasons: Sequence[str]) -> Dict[str, Any]:
|
| 289 | """Derive evidence_class / claim_eligible for one row of a run."""
|
| 290 | if record is None:
|
| 291 | reasons = ["no calibration record"]
|
| 292 | else:
|
| 293 | reasons = list(campaign_reasons) or row_problems(row, facts or {})
|
| 294 | if reasons:
|
| 295 | row["evidence_class"] = DEVELOPMENT_EVIDENCE_CLASS
|
| 296 | row["claim_eligible"] = False
|
| 297 | row["claim_ineligible_reasons"] = reasons[:5]
|
| 298 | for key in ("calibration_record", "calibration_record_sha256"):
|
| 299 | row.pop(key, None)
|
| 300 | else:
|
| 301 | row["evidence_class"] = CALIBRATED_EVIDENCE_CLASS
|
| 302 | row["claim_eligible"] = True
|
| 303 | row["claim_ineligible_reasons"] = []
|
| 304 | row["calibration_record"] = record
|
| 305 | row["calibration_record_sha256"] = record["record_sha256"]
|
| 306 | return row
|
| 307 |
|
| 308 |
|
| 309 | def gate(scale_rows: Sequence[Tuple[str, Dict[str, Any]]], inputs: Dict[str, List[Dict[str, Any]]],
|
| 310 | input_sha256: Dict[str, str], registry: Optional[Dict[str, Any]]) -> List[Tuple[str, Any, Any, Any, str]]:
|
| 311 | """publish_gate: every publishable scale row is re-verified by recomputation.
|
| 312 |
|
| 313 | ``inputs``/``input_sha256`` map each input path to its rows and content
|
| 314 | sha256; the calibration JSONL must be one of them. Returns refusals.
|
| 315 | """
|
| 316 | by_sha = {sha: path for path, sha in input_sha256.items()}
|
| 317 | # Inputs that are the calibration campaigns referenced by rows are evidence
|
| 318 | # FOR the gate, not measurements being published.
|
| 319 | campaign_paths = {by_sha.get((row.get("calibration_record") or {}).get("calibration_rows_sha256"))
|
| 320 | for _, row in scale_rows if isinstance(row.get("calibration_record"), dict)}
|
| 321 | campaign_paths.discard(None)
|
| 322 | verified: Dict[str, Tuple[Dict[str, Any], List[str]]] = {}
|
| 323 | run_probe_cache: Dict[Tuple[str, str], List[str]] = {}
|
| 324 | refused = []
|
| 325 | for path, row in scale_rows:
|
| 326 | if path in campaign_paths:
|
| 327 | continue
|
| 328 | if row.get("diagnostic") or row.get("returncode") == 77 or row.get("subject_kind") == "harness":
|
| 329 | continue
|
| 330 | where = (path, row.get("scenario"), row.get("operation"), row.get("subject"))
|
| 331 | if row.get("evidence_class") != CALIBRATED_EVIDENCE_CLASS or row.get("claim_eligible") is not True:
|
| 332 | refused.append((*where, f"evidence_class {row.get('evidence_class')!r} is not calibrated"))
|
| 333 | continue
|
| 334 | record = row.get("calibration_record")
|
| 335 | if not isinstance(record, dict) or row.get("calibration_record_sha256") != record.get("record_sha256"):
|
| 336 | refused.append((*where, "calibration record missing or its digest does not match the row"))
|
| 337 | continue
|
| 338 | key = record.get("record_sha256")
|
| 339 | if key not in verified:
|
| 340 | cal_sha = record.get("calibration_rows_sha256")
|
| 341 | cal_path = by_sha.get(cal_sha)
|
| 342 | verified[key] = verify_campaign(record, inputs.get(cal_path) if cal_path else None,
|
| 343 | cal_sha if cal_path else None, registry)
|
| 344 | facts, reasons = verified[key]
|
| 345 | if reasons:
|
| 346 | refused.append((*where, reasons[0]))
|
| 347 | continue
|
| 348 | problems = row_problems(row, facts)
|
| 349 | probe_key = (path, str(row.get("bench_id")))
|
| 350 | if probe_key not in run_probe_cache:
|
| 351 | run_rows = [r for r in inputs.get(path, []) if r.get("bench_id") == row.get("bench_id")]
|
| 352 | run_probe_cache[probe_key] = probe_verdict(run_rows)[0]
|
| 353 | problems += [f"published run: {reason}" for reason in run_probe_cache[probe_key]]
|
| 354 | if problems:
|
| 355 | refused.append((*where, problems[0]))
|
| 356 | return refused
|