2026-09-13 15:04:01 -05:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
"""Persist bounded, non-secret evidence for provider model evaluations."""
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import hashlib
|
|
|
|
|
import json
|
|
|
|
|
import os
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
from typing import Any, Iterable, Mapping
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCHEMA_VERSION = 1
|
|
|
|
|
EVALUATION_VERSION = "capability-v1"
|
|
|
|
|
RETRY_SECONDS = 6 * 60 * 60
|
2026-09-13 15:46:39 -05:00
|
|
|
TRANSIENT_RETRY_SECONDS = 15 * 60
|
2026-09-13 15:04:01 -05:00
|
|
|
FAILURE_CLASSES = frozenset(
|
|
|
|
|
{
|
|
|
|
|
"auth", "network", "timeout", "rate_limited", "provider",
|
|
|
|
|
"invalid_response", "truncated",
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def metadata_fingerprint(model: str, metadata: Mapping[str, Any]) -> str:
|
|
|
|
|
"""Bind cached evidence to the advertised, non-secret model metadata."""
|
|
|
|
|
# These two fields are injected only after this fingerprint admits a
|
|
|
|
|
# candidate. Excluding them keeps an accepted cache record stable across
|
|
|
|
|
# the publish/evaluate/publish refresh cycle.
|
|
|
|
|
source = {
|
|
|
|
|
key: value
|
|
|
|
|
for key, value in metadata.items()
|
|
|
|
|
if key not in {"evaluated_capability_role", "evaluation_provenance"}
|
|
|
|
|
}
|
|
|
|
|
value = json.dumps(
|
|
|
|
|
{"model": model, "metadata": source},
|
|
|
|
|
sort_keys=True,
|
|
|
|
|
separators=(",", ":"),
|
|
|
|
|
default=str,
|
|
|
|
|
)
|
|
|
|
|
return hashlib.sha256(value.encode("utf-8")).hexdigest()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def empty_store() -> dict[str, Any]:
|
|
|
|
|
"""Return the stable on-disk envelope used by the evaluator."""
|
|
|
|
|
return {"schema_version": SCHEMA_VERSION, "evaluations": {}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_store(path: Path) -> dict[str, Any]:
|
|
|
|
|
"""Load valid evidence, refusing malformed or incompatible state."""
|
|
|
|
|
try:
|
|
|
|
|
value = json.loads(path.read_text(encoding="utf-8"))
|
|
|
|
|
except (OSError, TypeError, ValueError, json.JSONDecodeError):
|
|
|
|
|
return empty_store()
|
|
|
|
|
if not isinstance(value, dict) or value.get("schema_version") != SCHEMA_VERSION:
|
|
|
|
|
return empty_store()
|
|
|
|
|
evaluations = value.get("evaluations")
|
|
|
|
|
return value if isinstance(evaluations, dict) else empty_store()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def write_store(path: Path, store: Mapping[str, Any]) -> None:
|
|
|
|
|
"""Atomically write evidence without retaining provider response text."""
|
|
|
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
content = json.dumps(dict(store), indent=2, sort_keys=True) + "\n"
|
|
|
|
|
temporary = path.with_name(f".{path.name}.{os.getpid()}.tmp")
|
|
|
|
|
temporary.write_text(content, encoding="utf-8")
|
|
|
|
|
os.chmod(temporary, 0o644)
|
|
|
|
|
os.replace(temporary, path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def record_key(provider: str, model: str) -> str:
|
|
|
|
|
"""Return a collision-safe provider/model identity for JSON storage."""
|
|
|
|
|
return f"{provider}:{model}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def reusable_success(
|
|
|
|
|
record: Mapping[str, Any] | None, fingerprint: str, *, version: str = EVALUATION_VERSION
|
|
|
|
|
) -> bool:
|
|
|
|
|
"""Accept a cache hit only for the identical metadata and eval version."""
|
|
|
|
|
return bool(
|
|
|
|
|
isinstance(record, Mapping)
|
|
|
|
|
and record.get("metadata_fingerprint") == fingerprint
|
|
|
|
|
and record.get("eval_version") == version
|
|
|
|
|
and record.get("result") == "pass"
|
|
|
|
|
and record.get("role_fit") == "verified"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def retry_due(record: Mapping[str, Any] | None, now: int) -> bool:
|
|
|
|
|
"""Avoid repeatedly spending a refresh on one non-passing model."""
|
|
|
|
|
if not isinstance(record, Mapping) or record.get("result") == "pass":
|
|
|
|
|
return True
|
|
|
|
|
retry_after = record.get("retry_after")
|
|
|
|
|
return not isinstance(retry_after, int) or now >= retry_after
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def unavailable_record(
|
|
|
|
|
*, provider: str, model: str, fingerprint: str, role: str, efforts: list[str],
|
|
|
|
|
failure_class: str, now: int, input_tokens: int = 0, output_tokens: int = 0,
|
|
|
|
|
latency_ms: int = 0, version: str = EVALUATION_VERSION,
|
|
|
|
|
) -> dict[str, Any]:
|
|
|
|
|
"""Represent transport trouble without treating it as model quality evidence."""
|
|
|
|
|
if failure_class not in FAILURE_CLASSES:
|
|
|
|
|
failure_class = "provider"
|
2026-09-13 15:46:39 -05:00
|
|
|
# The steward starts alongside its loopback brokers. Retry a local startup
|
|
|
|
|
# race on the next hourly refresh, while keeping provider failures backoffed.
|
|
|
|
|
retry_seconds = TRANSIENT_RETRY_SECONDS if failure_class == "network" else RETRY_SECONDS
|
2026-09-13 15:04:01 -05:00
|
|
|
return {
|
|
|
|
|
"provider": provider,
|
|
|
|
|
"model": model,
|
|
|
|
|
"metadata_fingerprint": fingerprint,
|
|
|
|
|
"eval_version": version,
|
|
|
|
|
"proposed_role": role,
|
|
|
|
|
"attempted_efforts": efforts,
|
|
|
|
|
"result": "unavailable",
|
|
|
|
|
"role_fit": "pending",
|
|
|
|
|
"failure_class": failure_class,
|
|
|
|
|
"last_attempt_at": now,
|
2026-09-13 15:46:39 -05:00
|
|
|
"retry_after": now + retry_seconds,
|
2026-09-13 15:04:01 -05:00
|
|
|
"tokens": {
|
|
|
|
|
"input": max(0, input_tokens),
|
|
|
|
|
"output": max(0, output_tokens),
|
|
|
|
|
"total": max(0, input_tokens) + max(0, output_tokens),
|
|
|
|
|
},
|
|
|
|
|
"latency_ms": max(0, latency_ms),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def accepted_outcomes(
|
|
|
|
|
observations: Iterable[Mapping[str, Any]],
|
|
|
|
|
) -> list[dict[str, Any]]:
|
|
|
|
|
"""Keep only externally verified acceptance outcomes with literal model IDs.
|
|
|
|
|
|
|
|
|
|
This deliberately ignores user preference, inferred quality, and incomplete
|
|
|
|
|
task reports. Callers may merge the returned summaries into model evidence
|
|
|
|
|
once they have a retained acceptance evaluator result.
|
|
|
|
|
"""
|
|
|
|
|
accepted: list[dict[str, Any]] = []
|
|
|
|
|
for item in observations:
|
|
|
|
|
if not isinstance(item, Mapping):
|
|
|
|
|
continue
|
|
|
|
|
provider = item.get("provider")
|
|
|
|
|
model = item.get("model")
|
|
|
|
|
if (
|
|
|
|
|
item.get("evidence_kind") != "acceptance"
|
|
|
|
|
or item.get("verified") is not True
|
|
|
|
|
or item.get("accepted") not in {True, False}
|
|
|
|
|
or not isinstance(provider, str)
|
|
|
|
|
or not provider
|
|
|
|
|
or not isinstance(model, str)
|
|
|
|
|
or not model
|
|
|
|
|
):
|
|
|
|
|
continue
|
|
|
|
|
accepted.append(
|
|
|
|
|
{
|
|
|
|
|
"provider": provider,
|
|
|
|
|
"model": model,
|
|
|
|
|
"accepted": item["accepted"],
|
|
|
|
|
"evidence_id": str(item.get("evidence_id") or "")[:128],
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
return accepted
|