a11oy / ayllu /selftest.py
betterwithage's picture
chore(sync): mirror backend .py + Dockerfile to Space (hf-sync-backend)
8fc7ac7 verified
Raw
History Blame Contribute Delete
3.54 kB
"""ayllu.selftest — offline self-test. Runs with NO a11oy modules and NO FastAPI.
Proves: 11 personas load with real soul prose; the tier router has an honest fallback;
a turn NEVER fabricates an answer without a backend; the autonomy gate is fail-closed;
the lounge deliberates honestly. Run: `python -m ayllu.selftest`.
"""
from __future__ import annotations
import asyncio
from ayllu.autonomy import gate
from ayllu.backend import backend_status
from ayllu.backend import model_complete as backend_model_complete
from ayllu.lounge import Lounge
from ayllu.loop import run_turn, select_tier
from ayllu.personas import ROSTER, get_persona
def main() -> None:
assert len(ROSTER) == 11, f"expected 11 personas, got {len(ROSTER)}"
for p in ROSTER:
sp = p.system_prompt()
assert sp and ("a11oy" in sp.lower() or "ayllu" in sp.lower()), \
f"soul empty or adrift: {p.name}"
assert p.approval_required is True, f"{p.name} must require approval (a11oy law)"
assert p.autonomy_level != "unbounded", f"{p.name} must not be unbounded"
assert select_tier(0.2)["route"] in ("small/local", "large/cloud")
assert select_tier(0.9)["route"] in ("small/local", "large/cloud")
# A turn with no injected model backend must NOT fabricate an answer.
turn = asyncio.run(run_turn(get_persona("amaru"), "Design a bounded plan."))
assert turn["answer"] is None, "must not fabricate an answer without a backend"
assert "not injected" in turn["honesty"], turn["honesty"]
# Autonomy gate: attestation is the binding fail-closed gate; Λ floor is advisory.
assert gate("deploy", state_changing=True)["allow"] is False
g_attested = gate("deploy", state_changing=True, two_person_attested=True)
assert g_attested["allow"] is True
assert g_attested["lambda_checked"] is False and g_attested["advisories"], \
"an unchecked Λ on a state-change must be annotated as advisory, not hidden"
assert gate("read", state_changing=False)["allow"] is True
assert gate("write", state_changing=True, two_person_attested=True,
lambda_score=0.5)["allow"] is False # below advisory Λ floor
assert gate("write", state_changing=True, two_person_attested=True,
lambda_score=0.95)["allow"] is True # Λ ≥ floor
# Lounge deliberation, honest (no backend => no fabricated answers).
lounge = Lounge()
res = asyncio.run(lounge.deliberate(
"What are the risks?", [get_persona("qhatuq"), get_persona("qhaway")],
publish_to_lounge=True))
assert len(res["rounds"]) == 2
assert all(r["answer"] is None for r in res["rounds"])
assert len(lounge.recent()) == 2
# Live backend seam is wired, and stays HONEST when a11oy's orchestrator is not
# importable in this offline env (stub, never a fabricated answer).
st = backend_status()
assert st["mode"] in ("unavailable", "stub", "unknown", "live"), st
wired = asyncio.run(run_turn(get_persona("ruwaq"), "Say hello.",
model_complete=backend_model_complete))
assert wired["stub"] in (True, False), wired
if st["mode"] == "unavailable":
assert wired["stub"] is True and wired["answer"] and \
"honest" in wired["answer"].lower(), wired
print(f"AYLLU SELFTEST OK - {len(ROSTER)} personas; tier router + bounded loop "
f"honest fallbacks; Lambda-gate fail-closed; lounge honest; backend mode="
f"{st['mode']}.")
if __name__ == "__main__":
main()