core/tests/test_expert_demo_contract.py
Shay 0493808215
feat(capability): implement ADR-0106 expert-demo promotion contract (#113)
Closes ADR-0106 acceptance evidence:

- ExpertDemoClaim dataclass + additive expert_demo_claims block on
  ReviewerRegistry (schema_version stays at 1; backward-compatible).
- New core/capability/expert_demo.py with derive_evidence_digest,
  evaluate_expert_demo, collect_domain_lanes, materialise_lane_results.
- core/capability/reporting.py: replaces the cognition-lane-only
  predicate (previous lines 418-433) with a domain-aware,
  reviewer-signed gate; ledger rows now also carry
  expert_demo_reason for operator legibility. Reviewer registry is
  fail-closed: an unloadable registry yields zero claims, so a broken
  registry never silently grants expert_demo=true.
- tests/test_expert_demo_contract.py covers all three ADR-0106
  invariants: requires_signature, domain_aware, replay_byte_equality;
  plus threshold + production-ledger-untouched gates. 12 new tests.
- tests/test_reviewer_registry.py extended with TestExpertDemoClaimsSchema
  covering omitted block, valid parse, unknown signer rejection,
  malformed digest rejection, duplicate domain rejection. 5 new tests.
- README index row + table preface updated to note expert_demo is
  contract-gated. Frontier list trimmed (ADR-0106 has landed).
- ADR-0106 Status flipped Proposed -> Accepted.

No domain row's expert_demo field flips by this PR -- only the contract
changes. Promotion of any ratified domain requires a follow-up ADR
(ADR-0107 reserved for mathematics_logic) plus a signed claim.
2026-05-22 11:39:09 -07:00

352 lines
12 KiB
Python

"""ADR-0106 — expert-demo promotion contract invariants.
Pins three load-bearing invariants:
1. ``expert_demo_requires_signature`` — no domain row may carry
``expert_demo=true`` without a corresponding ``expert_demo_claims``
entry whose digest reproduces the on-disk evidence bundle.
2. ``expert_demo_domain_aware`` — the reporting layer must consult only
lanes attached to a domain's ratified packs when computing
``expert_demo``. Cross-domain lane bleed (e.g. cognition-lane metrics
deciding a math promotion) is refused.
3. ``expert_demo_replay_byte_equality`` — re-running every consulted
lane at ``evidence_revision`` must reproduce the exact JSON bytes
hashed into ``claim_digest``. Drift demotes the row back to
``reasoning-capable``.
The current main-branch state of the ledger has zero domains with
``expert_demo=true``; these tests synthesize fixtures to prove the gate
behaves as ADR-0106 specifies, without flipping any production row.
"""
from __future__ import annotations
from core.capability.expert_demo import (
derive_evidence_digest,
evaluate_expert_demo,
)
from core.capability.reviewers import (
ExpertDemoClaim,
Reviewer,
ReviewerRegistry,
)
_GOOD_METRICS = {
"surface_groundedness": 0.97,
"term_capture_rate": 0.90,
"intent_accuracy": 0.96,
"versor_closure_rate": 1.0,
}
_FAB_METRICS = {"passed_rate": 1.0}
def _primary_reviewer() -> Reviewer:
return Reviewer(
reviewer_id="shay-j",
display_name="Joshua Shay",
role="primary",
domains=("*",),
review_scope=("pack", "proposal", "chain", "eval"),
provenance="adr-0092:bootstrap:2026-05-21",
)
def _build_registry(
reviewers: tuple[Reviewer, ...],
claims: tuple[ExpertDemoClaim, ...] = (),
) -> ReviewerRegistry:
return ReviewerRegistry(
schema_version=1, reviewers=reviewers, expert_demo_claims=claims
)
def _good_lane_results(lanes: tuple[str, ...]) -> dict[str, dict[str, dict]]:
out: dict[str, dict[str, dict]] = {}
for lane in lanes:
metrics = _FAB_METRICS if lane == "fabrication_control" else _GOOD_METRICS
out[lane] = {"public": dict(metrics), "holdout": dict(metrics)}
return out
class TestExpertDemoRequiresSignature:
def test_no_claim_refuses_promotion(self) -> None:
registry = _build_registry((_primary_reviewer(),))
verdict = evaluate_expert_demo(
domain_id="mathematics_logic",
reasoning_capable=True,
registry=registry,
domain_lanes=("inference_closure", "fabrication_control"),
lane_results=_good_lane_results(
("inference_closure", "fabrication_control")
),
)
assert verdict.passed is False
assert "no expert_demo_claims entry" in verdict.reason
def test_unsigned_lanes_refuse_promotion(self) -> None:
registry = _build_registry(())
verdict = evaluate_expert_demo(
domain_id="mathematics_logic",
reasoning_capable=True,
registry=registry,
domain_lanes=("inference_closure",),
lane_results=_good_lane_results(("inference_closure",)),
)
assert verdict.passed is False
def test_not_reasoning_capable_refuses_promotion(self) -> None:
registry = _build_registry((_primary_reviewer(),))
verdict = evaluate_expert_demo(
domain_id="mathematics_logic",
reasoning_capable=False,
registry=registry,
domain_lanes=("inference_closure",),
lane_results=_good_lane_results(("inference_closure",)),
)
assert verdict.passed is False
assert "not yet reasoning-capable" in verdict.reason
def test_signer_without_eval_scope_refuses_promotion(self) -> None:
domain = "mathematics_logic"
reviewer = Reviewer(
reviewer_id="math-pack-reviewer",
display_name="Math Pack Reviewer",
role="domain",
domains=(domain,),
review_scope=("pack", "chain"),
provenance="adr-0092:bootstrap:2026-05-21",
)
lanes = ("inference_closure", "fabrication_control")
results = _good_lane_results(lanes)
digest = derive_evidence_digest(
domain_id=domain,
evidence_revision="abc123",
evidence_lanes=lanes,
lane_results=results,
)
claim = ExpertDemoClaim(
domain_id=domain,
evidence_lanes=lanes,
evidence_revision="abc123",
signed_by="math-pack-reviewer",
claim_digest=digest,
)
registry = _build_registry((reviewer,), (claim,))
verdict = evaluate_expert_demo(
domain_id=domain,
reasoning_capable=True,
registry=registry,
domain_lanes=lanes,
lane_results=results,
)
assert verdict.passed is False
assert "cannot review eval-scope" in verdict.reason
class TestExpertDemoDomainAware:
def test_cross_domain_lane_bleed_refused(self) -> None:
"""A claim that cites a cognition lane for a math promotion fails."""
domain = "mathematics_logic"
math_lanes = ("inference_closure", "fabrication_control")
bad_claim_lanes = ("cognition",)
results = _good_lane_results(bad_claim_lanes + math_lanes)
digest = derive_evidence_digest(
domain_id=domain,
evidence_revision="rev1",
evidence_lanes=bad_claim_lanes,
lane_results=results,
)
claim = ExpertDemoClaim(
domain_id=domain,
evidence_lanes=bad_claim_lanes,
evidence_revision="rev1",
signed_by="shay-j",
claim_digest=digest,
)
registry = _build_registry((_primary_reviewer(),), (claim,))
verdict = evaluate_expert_demo(
domain_id=domain,
reasoning_capable=True,
registry=registry,
domain_lanes=math_lanes,
lane_results=results,
)
assert verdict.passed is False
assert "lanes not attached to domain" in verdict.reason
def test_in_domain_lanes_accepted(self) -> None:
domain = "mathematics_logic"
lanes = ("inference_closure", "fabrication_control")
results = _good_lane_results(lanes)
digest = derive_evidence_digest(
domain_id=domain,
evidence_revision="rev1",
evidence_lanes=lanes,
lane_results=results,
)
claim = ExpertDemoClaim(
domain_id=domain,
evidence_lanes=lanes,
evidence_revision="rev1",
signed_by="shay-j",
claim_digest=digest,
)
registry = _build_registry((_primary_reviewer(),), (claim,))
verdict = evaluate_expert_demo(
domain_id=domain,
reasoning_capable=True,
registry=registry,
domain_lanes=lanes,
lane_results=results,
)
assert verdict.passed is True
assert verdict.derived_digest == digest
class TestExpertDemoReplayByteEquality:
def test_digest_is_stable_across_invocations(self) -> None:
lanes = ("inference_closure", "fabrication_control")
results = _good_lane_results(lanes)
first = derive_evidence_digest(
domain_id="mathematics_logic",
evidence_revision="rev1",
evidence_lanes=lanes,
lane_results=results,
)
second = derive_evidence_digest(
domain_id="mathematics_logic",
evidence_revision="rev1",
evidence_lanes=lanes,
lane_results=results,
)
assert first == second
def test_digest_is_order_independent_on_lanes(self) -> None:
results = _good_lane_results(("a", "b", "c"))
d1 = derive_evidence_digest(
domain_id="d",
evidence_revision="rev1",
evidence_lanes=("a", "b", "c"),
lane_results=results,
)
d2 = derive_evidence_digest(
domain_id="d",
evidence_revision="rev1",
evidence_lanes=("c", "a", "b"),
lane_results=results,
)
assert d1 == d2
def test_drift_in_results_demotes_row(self) -> None:
domain = "mathematics_logic"
lanes = ("inference_closure", "fabrication_control")
original = _good_lane_results(lanes)
original_digest = derive_evidence_digest(
domain_id=domain,
evidence_revision="rev1",
evidence_lanes=lanes,
lane_results=original,
)
claim = ExpertDemoClaim(
domain_id=domain,
evidence_lanes=lanes,
evidence_revision="rev1",
signed_by="shay-j",
claim_digest=original_digest,
)
drifted = _good_lane_results(lanes)
drifted["inference_closure"]["public"]["intent_accuracy"] = 0.99
registry = _build_registry((_primary_reviewer(),), (claim,))
verdict = evaluate_expert_demo(
domain_id=domain,
reasoning_capable=True,
registry=registry,
domain_lanes=lanes,
lane_results=drifted,
)
assert verdict.passed is False
assert "replay drift" in verdict.reason
assert verdict.derived_digest is not None
assert verdict.derived_digest != original_digest
class TestExpertDemoThresholds:
def test_below_threshold_metric_refuses(self) -> None:
domain = "mathematics_logic"
lanes = ("inference_closure", "fabrication_control")
results = _good_lane_results(lanes)
results["inference_closure"]["holdout"]["surface_groundedness"] = 0.50
digest = derive_evidence_digest(
domain_id=domain,
evidence_revision="rev1",
evidence_lanes=lanes,
lane_results=results,
)
claim = ExpertDemoClaim(
domain_id=domain,
evidence_lanes=lanes,
evidence_revision="rev1",
signed_by="shay-j",
claim_digest=digest,
)
registry = _build_registry((_primary_reviewer(),), (claim,))
verdict = evaluate_expert_demo(
domain_id=domain,
reasoning_capable=True,
registry=registry,
domain_lanes=lanes,
lane_results=results,
)
assert verdict.passed is False
assert "surface_groundedness" in verdict.reason
assert "below threshold" in verdict.reason
def test_fabrication_control_failure_refuses(self) -> None:
domain = "mathematics_logic"
lanes = ("inference_closure", "fabrication_control")
results = _good_lane_results(lanes)
results["fabrication_control"]["holdout"]["passed_rate"] = 0.8
digest = derive_evidence_digest(
domain_id=domain,
evidence_revision="rev1",
evidence_lanes=lanes,
lane_results=results,
)
claim = ExpertDemoClaim(
domain_id=domain,
evidence_lanes=lanes,
evidence_revision="rev1",
signed_by="shay-j",
claim_digest=digest,
)
registry = _build_registry((_primary_reviewer(),), (claim,))
verdict = evaluate_expert_demo(
domain_id=domain,
reasoning_capable=True,
registry=registry,
domain_lanes=lanes,
lane_results=results,
)
assert verdict.passed is False
assert "fabrication_control" in verdict.reason
class TestProductionLedgerUntouched:
"""ADR-0106 §Acceptance: no domain row's expert_demo field flips."""
def test_no_production_domain_promoted_by_this_adr(self) -> None:
from core.capability.reporting import ledger_report
report = ledger_report()
promoted = [
row["domain"]
for row in report.get("domains", [])
if row.get("predicates", {}).get("expert_demo")
]
assert promoted == [], (
f"ADR-0106 must not promote any domain by code change alone; "
f"got: {promoted}"
)