File size: 2,444 Bytes
5607db3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
"""
echo/test_age_invariant.py
--------------------------
Regression guard for the age invariant: across the whole tree, a child's age
must equal parent.age + years_elapsed, and the root must keep its base_age.

Age is arithmetic, not generation — the model's free-form `age` must never be
able to break the tree's math. Runs on MockLLM (no GPU, no ML deps).

    python -m echo.test_age_invariant
"""

from __future__ import annotations

from echo.core.orchestrator import Orchestrator
from echo.llm.client import MockLLM
from echo.tools.research import MockResearch
from echo.tools.voice import MockVoice


def _orch() -> Orchestrator:
    return Orchestrator(MockLLM(seed=0), MockResearch(), MockVoice())


def test_root_keeps_base_age() -> None:
    root = _orch().seed("I stayed in Brazil instead of moving abroad", base_age=22)
    assert root.facts.age == 22, f"root age {root.facts.age} != base_age 22 (Bug 3)"


def test_child_age_is_parent_plus_years() -> None:
    orch = _orch()
    root = orch.seed("I stayed in Brazil instead of moving abroad", base_age=22)
    child = orch.choose_fork(root.node_id, 0, years=5)
    assert child.years_elapsed == 5, f"years_elapsed {child.years_elapsed} != 5"
    expected = root.facts.age + 5
    assert child.facts.age == expected, \
        f"child age {child.facts.age} != expected {expected} (Bug 1)"


def test_age_invariant_holds_down_a_branch() -> None:
    """Grow three generations and assert age math at every edge."""
    orch = _orch()
    node = orch.seed("I stayed in Brazil instead of moving abroad", base_age=30)
    for _ in range(3):
        parent = node
        node = orch.choose_fork(parent.node_id, 0, years=7)
        expected = parent.facts.age + 7
        assert node.facts.age == expected, \
            f"depth {node.depth}: age {node.facts.age} != expected {expected}"


def main() -> int:
    tests = [
        test_root_keeps_base_age,
        test_child_age_is_parent_plus_years,
        test_age_invariant_holds_down_a_branch,
    ]
    failed = 0
    for t in tests:
        try:
            t()
            print(f"  PASS  {t.__name__}")
        except AssertionError as e:
            failed += 1
            print(f"  FAIL  {t.__name__}: {e}")
    print("=" * 50)
    if failed:
        print(f"{failed}/{len(tests)} FAILED")
        return 1
    print(f"ALL {len(tests)} PASSED ✓")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())