mindXtrain / tests /test_governance.py
Gregory-L's picture
fork mindXtrain from GitHub (Professor-Codephreak/mindXtrain@661bd41) as the mindX-specific line
dfb775d verified
Raw History Blame Contribute Delete
5.57 kB
"""Governance: classroom (graduate) → boardroom (any-N) → dojo (prime-N) settlement."""
from __future__ import annotations
import pytest
from mindxtrain.governance import (
Boardroom,
Dojo,
Member,
graduate,
is_prime,
nearest_prime,
next_prime,
settle_dispute,
)
from mindxtrain.governance.boardroom import board_from_preset
from mindxtrain.governance.dojo import prime_dojo_size
# ---- primes -----------------------------------------------------------------
@pytest.mark.parametrize(
("n", "expected"),
[(0, False), (1, False), (2, True), (3, True), (4, False), (5, True),
(9, False), (11, True), (15, False), (17, True), (97, True), (100, False)],
)
def test_is_prime(n, expected):
assert is_prime(n) is expected
def test_next_prime():
assert next_prime(2) == 3
assert next_prime(8) == 11
assert next_prime(13) == 17
def test_nearest_prime_rounds_up_on_tie():
assert nearest_prime(4) == 5 # 3 and 5 equidistant → up
assert nearest_prime(3) == 3
assert nearest_prime(1) == 2
def test_prime_dojo_size_is_odd_prime_ge3():
for req in range(0, 12):
n = prime_dojo_size(req)
assert n >= 3 and is_prime(n)
assert prime_dojo_size(2) == 3 # 2 excluded (even, can tie)
assert prime_dojo_size(4) == 5
# ---- boardroom (any N) ------------------------------------------------------
def _board(n):
return Boardroom(members=[Member(id=f"m{i}", role="generalist") for i in range(n)])
def test_boardroom_any_number_of_members():
for n in (1, 2, 4, 6, 10): # any N, not just prime
b = _board(n)
assert len(b.members) == n
def test_boardroom_approves_on_majority():
b = _board(4)
ballot = {"m0": "approve", "m1": "approve", "m2": "approve", "m3": "reject"}
d = b.convene("promote actor x", ballot)
assert d.outcome == "approved"
assert d.disputed is False
assert d.approvals == 3 and d.rejections == 1
def test_boardroom_tie_is_disputed():
b = _board(4)
ballot = {"m0": "approve", "m1": "approve", "m2": "reject", "m3": "reject"}
d = b.convene("promote actor x", ballot)
assert d.outcome == "disputed"
assert d.disputed is True
def test_boardroom_no_quorum_is_disputed():
b = Boardroom(members=[Member(id=f"m{i}") for i in range(4)], quorum=0.75)
# Only 2 decisive votes of 4; quorum needs ceil(0.75*4)=3.
ballot = {"m0": "approve", "m1": "reject"} # m2, m3 abstain
d = b.convene("x", ballot)
assert d.disputed is True
assert "no quorum" in d.rationale
def test_boardroom_callable_ballot_and_preset():
members = board_from_preset("classic_triad")
b = Boardroom(members=members)
# advocate approves, others reject → rejected.
d = b.convene("x", lambda m, _motion: "approve" if m.role == "advocate" else "reject")
assert d.outcome == "rejected"
assert len(b.members) == 3
# ---- dojo (prime N) ---------------------------------------------------------
def test_dojo_rejects_non_prime_panel():
from pydantic import ValidationError
with pytest.raises(ValidationError):
Dojo(judges=[Member(id=f"j{i}") for i in range(4)]) # 4 not prime
with pytest.raises(ValidationError):
Dojo(judges=[Member(id="j0"), Member(id="j1")]) # 2 excluded (even)
def test_dojo_accepts_odd_prime_panel():
d = Dojo(judges=[Member(id=f"j{i}") for i in range(5)])
assert len(d.judges) == 5
def test_dojo_sized_rounds_to_prime():
d = Dojo.sized(4)
assert len(d.judges) == 5 and is_prime(len(d.judges))
def test_dojo_settles_without_tie():
d = Dojo.sized(3)
verdict = d.settle("promote actor x",
{"judge-0": "approve", "judge-1": "approve", "judge-2": "reject"})
assert verdict.settled is True
assert verdict.winner == "approve"
assert verdict.approvals + verdict.rejections == 3 # no abstentions
def test_dojo_requires_every_judge_to_vote():
d = Dojo.sized(3)
with pytest.raises(ValueError, match="did not vote"):
d.settle("x", {"judge-0": "approve"})
# ---- end-to-end flow: classroom → boardroom → dojo --------------------------
class _Report:
"""Minimal ImprintReport stand-in for the graduation gate."""
imprinted = True
imprint_delta = 0.04
def test_graduation_then_disputed_board_settled_by_dojo():
grad = graduate(_Report(), run_id="actor-1", min_delta=0.0)
assert grad.graduated is True
assert "actor-1" in grad.motion
board = _board(4)
tie = {"m0": "approve", "m1": "approve", "m2": "reject", "m3": "reject"}
decision = board.convene(grad.motion, tie)
assert decision.disputed is True
dojo = Dojo.sized(len(board.members)) # 4 → 5 judges (odd prime)
verdict = settle_dispute(
decision, dojo,
{"judge-0": "approve", "judge-1": "approve", "judge-2": "approve",
"judge-3": "reject", "judge-4": "reject"},
)
assert verdict.settled is True
assert verdict.winner == "approve" # 3-2, no tie possible
def test_settle_dispute_refuses_undisputed_decision():
board = _board(3)
decision = board.convene("x", {"m0": "approve", "m1": "approve", "m2": "reject"})
assert decision.disputed is False
with pytest.raises(ValueError, match="not disputed"):
settle_dispute(decision, Dojo.sized(3), {})
def test_graduation_fails_when_not_imprinted():
class _Weak:
imprinted = False
imprint_delta = 0.0
grad = graduate(_Weak(), run_id="actor-2")
assert grad.graduated is False
assert grad.reasons