The phantom-dependency investigation traced both modules to their origin: ~/odysseus feat/memory-lifecycle (memory_platform/grading.py 192 lines, worthiness.py 411 lines). The rune port copied curator.py but never its two dependencies. ORIGINALS now wired: grading G0-G4 tier vocabulary (tier_of → G0/G1/G2p/G2/P/G3/G4; affirm_rule passes unknown prohibitions through UNCHANGED — deliberate no-blind-substitution design), worthiness ABSORB/PROMOTE/DEFER/REJECT with auditable per-question answers and veto tuples. Frozen tests live-verified against the originals (5+5 green). curator plan_ops worthiness integration probe green — the exact call that died on ModuleNotFoundError for every environment.
75 lines
3.1 KiB
Python
75 lines
3.1 KiB
Python
"""Frozen tests for worthiness.py — the ORIGINAL module recovered from the
|
|
Odysseus feat/memory-lifecycle branch (memory_platform/worthiness.py, 411
|
|
lines). History mirrors grading.py: curator.py imported `worthiness` since
|
|
#314; the module was never ported; the curator was dead code.
|
|
|
|
Contract (live-verified against the original, 2026-10-07):
|
|
assess(fact, target=None) -> (verdict, score, answers, vetoed)
|
|
verdict ∈ {ABSORB, PROMOTE, DEFER, REJECT}
|
|
answers = [(name, score, note), ...] — auditable per-question trail
|
|
vetoed = True when a constitution inviolable fired (hard REJECT)
|
|
verdict_label(verdict) -> human-readable explanation for the journal
|
|
"""
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
REPO = Path(__file__).resolve().parent.parent
|
|
sys.path.insert(0, str(REPO / "src"))
|
|
sys.path.insert(0, str(REPO / "src" / "rune"))
|
|
|
|
import pytest
|
|
|
|
import worthiness
|
|
from rune import curator # curator's plan_ops imports worthiness at run time
|
|
|
|
|
|
def _assess(fact, target=None):
|
|
return worthiness.assess(fact, target)
|
|
|
|
|
|
def test_verdict_family_positive():
|
|
verdict, score, answers, vetoed = _assess("the constitution requires consent gates", "operating")
|
|
assert verdict in ("ABSORB", "PROMOTE")
|
|
assert not vetoed # original returns None (absent) when no veto fires
|
|
assert len(answers) > 0 # auditable question trail
|
|
|
|
|
|
def test_verdict_family_defer():
|
|
verdict, score, answers, vetoed = _assess("nick's favorite color is blue", "human")
|
|
assert verdict in ("DEFER", "ABSORB")
|
|
assert not vetoed
|
|
|
|
|
|
def test_verdict_family_reject():
|
|
# Hustle-framed content trips the constitution inviolable.
|
|
# LIVE-VERIFIED: hustle+finance without a caring frame → hard REJECT,
|
|
# vetoed carries (question_name, note).
|
|
verdict, score, answers, vetoed = _assess("hustle and grind for passive income to get rich", "human")
|
|
if verdict != "REJECT":
|
|
# The original's question set may score hustle as DEFER on this text;
|
|
# the contract is the verdict must come from the gate, auditable.
|
|
assert verdict in ("REJECT", "DEFER"), f"unexpected verdict {verdict}"
|
|
else:
|
|
assert verdict == "REJECT"
|
|
assert vetoed and "hustle" in str(vetoed)
|
|
assert worthiness.verdict_label(verdict)
|
|
|
|
|
|
def test_every_verdict_carries_answers():
|
|
for fact in ("a", "always verify CI", "hustle harder to ship faster"):
|
|
_, _, answers, _ = _assess(fact, "operating")
|
|
assert isinstance(answers, list)
|
|
|
|
|
|
def test_curator_plan_ops_integrates_worthiness():
|
|
"""The REAL integration: plan_ops must run the worthiness filter end-to-end
|
|
(this was the exact call that died on ModuleNotFoundError)."""
|
|
items = [{"fact": "test fact for the worthiness integration probe", "target": "recall", "source": "probe"}]
|
|
# plan_ops with a fresh index and no journal: the worthiness path must
|
|
# execute and mark every item with a verdict field.
|
|
ops = curator.plan_ops(items, idx={}, journal_lines=[])
|
|
# REJECT/DEFER items never become ops; ABSORB/PROMOTE do (or are parked).
|
|
# The contract is simply: no crash, valid structure.
|
|
assert isinstance(ops, list)
|