Files
rune/scripts/gen_outcome_utility_truth.py
T
Nick 14805261d2 feat(outcome_utility): port to FULL Rust — dichotomy wave (batch-h)
Language verdict (docs/language-dichotomy-ledger.md): RUST — Law 4/W6:
deterministic scoring/clamping compute (utility caps, floors, bounded
decay); no I/O, pure decision math.

- src/rust/outcome_utility: doc-envelope FFI (ou_apply_outcome,
  ou_apply_stale, ou_retrieval_alone, ou_record_verified_outcome,
  ou_free_string); frozen-truth battery embedded (battery.rs) — 97
  frozen-oracle cases replayed VERBATIM, bit-exact.
- src/rune/ou_loader.py: ctypes loader mirroring broker_loader.py;
  RUNE_OU_CORE=python pin honored inside the loader.
- src/rune/outcome_utility.py: facade delegation; the utility TABLE
  stays Python (storage in the caller's language); RUNE_OU_CORE=python
  pins the oracle floor.
- scripts/gen_outcome_utility_truth.py: frozen corpus generator
  (poisoned-truth law: oracle-only, deep-copied inputs, all branches).
- tests/test_outcome_utility_port.py: frozen replay VERBATIM, pin
  probe, facade delegation, oracle sanity, seeded live-parity sweep
  (500 rounds, seed 2479) — parity 100%.

Verification: cargo test green (97/97 frozen), cargo clippy -D
warnings 0, pytest 6/6 both pins, ruff clean.
Contract BUILDER-2026-10-13T00:04:22Z-4156e1-factory-batch-h
(builder=factory-batch-h) — building.
2026-10-13 04:28:57 +01:00

122 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Freeze the dichotomy-wave truth corpus for src/rune/outcome_utility.py.
LAW (poisoned-truth): RUNE_OU_CORE=python is pinned at the top — truth is
generated by the PYTHON ORACLE ONLY, never by the kernel under test.
Every public function is exercised across ALL branches (helpful/ignored/
unknown × cap/floor boundaries; stale 0/positive/negative/clamping;
retrieval passthrough; record on new/existing/partial entries with
driven cap and floor saturation). Inputs are DEEP-COPIED before each
oracle call — the frozen corpus is byte-stable and carries no live
state. Output: src/rust/outcome_utility/src/frozen_outcome_utility_truth.json
"""
from __future__ import annotations
import copy
import json
import os
import sys
from pathlib import Path
os.environ["RUNE_OU_CORE"] = "python" # poisoned-truth law
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "src"))
import rune.outcome_utility as ou # noqa: E402
OUT = REPO / "src" / "rust" / "outcome_utility" / "src" / "frozen_outcome_utility_truth.json"
cases: list[dict] = []
def case(fn: str, name: str, args: dict):
"""Call the oracle on a DEEP COPY of the args; freeze the verdict."""
frozen_args = copy.deepcopy(args)
live_args = copy.deepcopy(args)
if fn == "apply_outcome":
expect = ou.apply_outcome(**live_args)
elif fn == "apply_stale":
expect = ou.apply_stale(**live_args)
elif fn == "retrieval_alone":
expect = ou.retrieval_alone(**live_args)
elif fn == "record_verified_outcome":
# store=None ≡ a fresh dict in the oracle; freeze the fresh dict so
# the mutation is captured (the FFI returns the table it built).
store_arg = live_args.get("store")
if store_arg is None:
store_arg = {}
summary = ou.record_verified_outcome(
live_args["entry_id"], live_args["outcome"], store_arg)
expect = {"summary": summary, "store": store_arg}
else: # pragma: no cover — generator typo guard
raise ValueError(fn)
cases.append({"fn": fn, "name": name, "args": frozen_args, "expect": expect})
# ── apply_outcome: all three branches × cap/floor boundaries ────────────────
for u in (0.0, 0.5, 0.95, 1.0, 1.0, -0.5, -1.0, 0.9499999, -1.0):
case("apply_outcome", f"helpful u={u!r}", {"utility": u, "outcome": "helpful"})
for u in (0.0, 0.5, -0.95, -1.0, -1.0, 1.0, -0.9499999):
case("apply_outcome", f"ignored u={u!r}", {"utility": u, "outcome": "ignored"})
for o in ("unknown", "", "HELPFUL", "helpful ", "partial", "verified"):
case("apply_outcome", f"unknown o={o!r}", {"utility": 0.42, "outcome": o})
# ── apply_stale: zero/negative/positive turns, clamp boundaries ─────────────
for u, t in ((0.5, 0), (0.5, 1), (0.5, 2), (0.5, 5), (1.0, 10), (-0.5, 3),
(-0.5, -3), (0.0, 60), (0.0, -60), (1.0, 200), (-1.0, 0),
(0.99, 100), (-0.02, 1000), (0.42, 1000000)):
case("apply_stale", f"stale u={u!r} t={t}", {"utility": u, "stale_turns": t})
# ── retrieval_alone: the anti-salience passthrough ──────────────────────────
for u in (0.0, 1.0, -1.0, 0.42, -0.77, 12345.678):
case("retrieval_alone", f"retrieval u={u!r}", {"utility": u})
# ── record_verified_outcome: new / existing / partial entries ───────────────
case("record_verified_outcome", "new entry default store",
{"entry_id": 1, "outcome": "helpful", "store": None})
case("record_verified_outcome", "new entry empty store",
{"entry_id": 7, "outcome": "ignored", "store": {}})
case("record_verified_outcome", "existing helpful",
{"entry_id": 1, "outcome": "helpful",
"store": {1: {"utility": 0.5, "confidence": 0.8}}})
case("record_verified_outcome", "existing ignored",
{"entry_id": 2, "outcome": "ignored",
"store": {2: {"utility": 0.5, "confidence": 0.8}}})
case("record_verified_outcome", "existing unknown outcome",
{"entry_id": 3, "outcome": "mystery",
"store": {3: {"utility": 0.25, "confidence": 0.9}}})
case("record_verified_outcome", "existing no confidence key",
{"entry_id": 4, "outcome": "helpful",
"store": {4: {"utility": 0.3}}})
case("record_verified_outcome", "existing no utility key",
{"entry_id": 5, "outcome": "ignored",
"store": {5: {"confidence": 0.1}}})
case("record_verified_outcome", "entry id zero",
{"entry_id": 0, "outcome": "helpful", "store": {}})
case("record_verified_outcome", "negative entry id",
{"entry_id": -3, "outcome": "ignored", "store": {}})
case("record_verified_outcome", "large entry id",
{"entry_id": 2**62, "outcome": "helpful", "store": {}})
# driven saturation: repeated outcomes walk utility to cap and floor
for i, outcome in enumerate(["helpful"] * 20):
case("record_verified_outcome", f"cap walk {i}",
{"entry_id": 10, "outcome": outcome,
"store": {10: {"utility": min(1.0, 0.1 * i), "confidence": 0.5}}})
for i, outcome in enumerate(["ignored"] * 25):
case("record_verified_outcome", f"floor walk {i}",
{"entry_id": 11, "outcome": outcome,
"store": {11: {"utility": max(-1.0, -0.05 * i), "confidence": 0.5}}})
doc = {
"module": "outcome_utility",
"frozen_ts": "2026-10-13T00:00:00Z",
"generator": "scripts/gen_outcome_utility_truth.py",
"pins": {"RUNE_OU_CORE": "python"},
"cases": cases,
}
OUT.parent.mkdir(parents=True, exist_ok=True)
OUT.write_text(json.dumps(doc, indent=1) + "\n")
print(f"frozen {len(cases)} cases -> {OUT}")