tests/test_trace.py
2.3 KB · 79 lines · python Raw
1 """Tests for ReasoningTrace."""
2
3 from __future__ import annotations
4
5 import pytest
6
7 from pqc_reasoning_ledger import (
8 ChainBrokenError,
9 ReasoningStep,
10 ReasoningTrace,
11 StepKind,
12 TraceSealedError,
13 )
14
15
16 def test_create_populates_trace_id() -> None:
17 trace = ReasoningTrace.create(model_did="did:x", model_version="1")
18 assert trace.metadata.trace_id.startswith("urn:pqc-trace:")
19 assert trace.metadata.created_at
20 assert trace.steps == []
21 assert trace.sealed is False
22 assert trace.current_hash == "0" * 64
23
24
25 def test_append_first_step_sets_current_hash() -> None:
26 trace = ReasoningTrace.create(model_did="did:x", model_version="1")
27 step = ReasoningStep.create(
28 kind=StepKind.THOUGHT,
29 content="first thought",
30 step_number=1,
31 previous_step_hash="0" * 64,
32 )
33 trace.append(step)
34 assert trace.current_hash == step.step_hash
35 assert len(trace.steps) == 1
36
37
38 def test_append_chain_broken_raises() -> None:
39 trace = ReasoningTrace.create(model_did="did:x", model_version="1")
40 # Step 1 ok
41 s1 = ReasoningStep.create(StepKind.THOUGHT, "t1", step_number=1)
42 trace.append(s1)
43 # Step 2 with wrong previous_step_hash
44 bad = ReasoningStep.create(
45 kind=StepKind.DEDUCTION,
46 content="t2",
47 step_number=2,
48 previous_step_hash="f" * 64, # wrong
49 )
50 with pytest.raises(ChainBrokenError):
51 trace.append(bad)
52
53
54 def test_append_wrong_step_number_raises() -> None:
55 trace = ReasoningTrace.create(model_did="did:x", model_version="1")
56 s1 = ReasoningStep.create(StepKind.THOUGHT, "t1", step_number=1)
57 trace.append(s1)
58 # Step with step_number 3 instead of 2
59 bad = ReasoningStep.create(
60 kind=StepKind.THOUGHT,
61 content="t2",
62 step_number=3,
63 previous_step_hash=trace.current_hash,
64 )
65 with pytest.raises(ChainBrokenError):
66 trace.append(bad)
67
68
69 def test_sealed_trace_rejects_append() -> None:
70 trace = ReasoningTrace.create(model_did="did:x", model_version="1")
71 s1 = ReasoningStep.create(StepKind.THOUGHT, "t1", step_number=1)
72 trace.append(s1)
73 trace.sealed = True
74 s2 = ReasoningStep.create(
75 StepKind.THOUGHT, "t2", step_number=2, previous_step_hash=trace.current_hash
76 )
77 with pytest.raises(TraceSealedError):
78 trace.append(s2)
79