The final AGI-spine step (A INSTRUMENT → B WIRE → C DEEPEN → D CLOSE → E ESTIMATION).
The engine may now SERVE a DISCLOSED estimate for a query it would otherwise refuse —
but only for a predicate-class that has measured itself reliable, and never as fact.
This executes the ADR-0206 §5 cognition-path widening: the bridge's LICENSE node
(reliability_gate.license_for), previously "built — not yet called from serving", is now
called. govern_response returns APPROXIMATE iff a genuine licensed Action.SERVE
LicenseDecision is passed (STRICT for every other input — so every existing serving call
site is byte-identical); shape_surface DISCLOSES the estimate as "[approximate] …".
Mechanism:
- generate/determine/estimate.py — a BLIND converse-guesser: told p(a,b), asked p(b,a),
it commits the converse. It never reads the pack's symmetry metadata; whether the guess
is right is MEASURED, not assumed.
- evals/determination_estimation/ — the gold lane: run_practice (sealed, ADR-0199) folds
the converse-guesser over symmetric (sibling_of) vs directed (parent_of) cases, scored
against the pack's graph.edge.symmetric truth (gold independent of the solver). The gate
DISCRIMINATES: sibling_of earns SERVE (660 correct → Wilson floor 0.990046 ≥ θ_SERVE),
parent_of does not (660 wrong → 0.0). The license is earned by VOLUME — 657 perfect
commits is the exact θ_SERVE=0.99 threshold (656 is below).
- generate/determine/data/estimation_ledger.json — the ratified committed ledger,
hash-verified on load (a hand-edited ledger raises RatifiedLedgerError); it IS the
deterministic sealed-practice output (a GSM8K-style --check test pins this).
- chat/runtime.py — when a converse query is refused and the class holds a SERVE license,
the disclosed estimate is surfaced through the bridge (gated by config.estimation_enabled,
default OFF; only meaningful with accrue_realized_knowledge).
Invariants:
- wrong=0 by construction — an estimate is ALWAYS disclosed ([approximate]), never a silent
commit (UNVERIFIED_POSSIBLE is never in APPROXIMATE's admissible set), and only a genuine
ratified license widens (a forged {"licensed":True} dict / a PROPOSE license / an
unlicensed SERVE all stay STRICT). Defense-in-depth: type-gate ∧ admissible-set ∧
hardcoded disclosed state.
- never self-authored — ceilings stay at safe defaults (θ_SERVE=0.99); the engine cannot
raise its own bar. The ledger is sealed practice, hash-verified.
- session/serving only — no corpus/pack/identity/proposal/vault mutation; the HITL teaching
path is untouched. Deterministic; no clock/random.
- byte-identical for every non-E turn (the 2643 govern_response call passes no license).
Out of scope (separate ADR-0206 §5 PRs): the math-serving seam (select_self_verified,
touches the sealed metric), SITUATE (stakes), and the live FEED-BACK loop.
Verified green: smoke (90), architectural invariants (56), response_governance (321,
incl. the new license-gated widening test), the determination-estimation lane (12), and
the B/D/determine regression net. Four-lens adversarial review (disclosure/wrong=0,
calibration integrity, byte-identity, boundary/determinism): all held. Design:
docs/analysis/E-estimation-design-2026-06-06.md.
86 lines
3.6 KiB
Python
86 lines
3.6 KiB
Python
"""E — the serving-side SERVE license for the converse-guess.
|
|
|
|
Reads the **ratified, committed** estimation ledger (``data/estimation_ledger.json``)
|
|
and exposes, per predicate, whether the converse-guess has earned ``Action.SERVE``
|
|
under the safe default ceilings (θ_SERVE=0.99). The engine READS this artifact; it
|
|
never writes it. The artifact is the sealed-practice output of
|
|
``evals.determination_estimation.build_ledger`` — its ``content_sha256`` is verified on
|
|
load, so a hand-edited (un-ratified) ledger is rejected rather than silently trusted.
|
|
|
|
Determinism: the ledger is immutable ratified data, parsed once and cached; the gate
|
|
(``license_for``) is pure. No engine self-authorization — ceilings stay at the safe
|
|
defaults (raising one's own bar is structurally impossible, ADR-0175 invariant #4).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from functools import lru_cache
|
|
from pathlib import Path
|
|
|
|
from core.reliability_gate import Action, Ceilings, ClassTally, LicenseDecision, license_for
|
|
from formation.hashing import sha256_of
|
|
from generate.determine.estimate import converse_class_name
|
|
|
|
_LEDGER_PATH = Path(__file__).resolve().parent / "data" / "estimation_ledger.json"
|
|
|
|
|
|
class RatifiedLedgerError(ValueError):
|
|
"""The committed estimation ledger is missing, malformed, or tampered with."""
|
|
|
|
|
|
@lru_cache(maxsize=1)
|
|
def load_ratified_ledger() -> dict[str, ClassTally]:
|
|
"""Load + verify the ratified estimation ledger → per-class ``ClassTally``.
|
|
|
|
Raises :class:`RatifiedLedgerError` if the file is absent/malformed or its
|
|
recomputed ``content_sha256`` does not match the committed one (tamper-evidence:
|
|
only the sealed-practice output is trusted, never a hand-edited ledger).
|
|
"""
|
|
try:
|
|
artifact = json.loads(_LEDGER_PATH.read_text(encoding="utf-8"))
|
|
except (OSError, json.JSONDecodeError) as exc: # pragma: no cover - defensive
|
|
raise RatifiedLedgerError(f"cannot read ratified ledger: {exc}") from exc
|
|
|
|
classes = artifact.get("classes")
|
|
if not isinstance(classes, dict):
|
|
raise RatifiedLedgerError("ratified ledger has no 'classes' table")
|
|
if sha256_of(classes) != artifact.get("content_sha256"):
|
|
raise RatifiedLedgerError(
|
|
"ratified ledger content_sha256 mismatch — not the sealed-practice output"
|
|
)
|
|
|
|
ledger: dict[str, ClassTally] = {}
|
|
for cls, counts in classes.items():
|
|
ledger[cls] = ClassTally(
|
|
class_name=cls,
|
|
correct=int(counts.get("correct", 0)),
|
|
wrong=int(counts.get("wrong", 0)),
|
|
refused=int(counts.get("refused", 0)),
|
|
t2_verified=int(counts.get("t2_verified", 0)),
|
|
t2_agrees_gold=int(counts.get("t2_agrees_gold", 0)),
|
|
)
|
|
return ledger
|
|
|
|
|
|
def serve_license(
|
|
predicate: str,
|
|
*,
|
|
ledger: dict[str, ClassTally] | None = None,
|
|
ceilings: Ceilings | None = None,
|
|
) -> LicenseDecision | None:
|
|
"""The ``Action.SERVE`` license for ``predicate``'s converse-guess, or ``None``.
|
|
|
|
``None`` means the predicate-class is absent from the ratified ledger (no committed
|
|
evidence → never licensed; the caller refuses, the safe default). Otherwise the
|
|
deterministic ``license_for`` verdict under the safe default ceilings.
|
|
"""
|
|
ledger = ledger if ledger is not None else load_ratified_ledger()
|
|
tally = ledger.get(converse_class_name(predicate))
|
|
if tally is None:
|
|
return None
|
|
ceilings = ceilings if ceilings is not None else Ceilings.default()
|
|
return license_for(tally, Action.SERVE, ceilings)
|
|
|
|
|
|
__all__ = ["RatifiedLedgerError", "load_ratified_ledger", "serve_license"]
|