Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/context_compiler/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Only explicit user directives can mutate authoritative state.
"""

import json
import re
from copy import deepcopy
from dataclasses import dataclass
Expand Down Expand Up @@ -108,6 +109,20 @@ def state(self) -> State:
"""Return a defensive copy of the current authoritative state snapshot."""
return deepcopy(self._state)

def export_json(self) -> str:
"""Serialize authoritative state to canonical JSON."""
return json.dumps(self._state, sort_keys=True, separators=(",", ":"))

def import_json(self, payload: str) -> None:
"""Replace authoritative state from a JSON payload."""
state = _load_state_json(payload)
self._state = state
self._pending = None
self._pending_prompt = None
self._last_exclusive_fact_key = (
FOCUS_PRIMARY if state[STATE_FACTS][FOCUS_PRIMARY] is not None else None
)

def step(self, user_input: str) -> Decision:
"""Process one user input and return a deterministic Decision."""
if self._pending is not None:
Expand Down Expand Up @@ -247,6 +262,45 @@ def _initial_state() -> State:
}


def _load_state_json(payload: str) -> State:
try:
raw = json.loads(payload)
except json.JSONDecodeError as exc:
raise ValueError("Invalid JSON payload.") from exc

if not isinstance(raw, dict):
raise ValueError("Invalid state payload.")
if set(raw.keys()) != {STATE_FACTS, STATE_POLICIES, STATE_VERSION}:
raise ValueError("Invalid state payload.")

if raw[STATE_VERSION] != 1:
raise ValueError(f"Unsupported state version: {raw[STATE_VERSION]!r}")

facts = raw[STATE_FACTS]
policies = raw[STATE_POLICIES]
if not isinstance(facts, dict) or not isinstance(policies, dict):
raise ValueError("Invalid state payload.")
if set(facts.keys()) != {FOCUS_PRIMARY} or set(policies.keys()) != {POLICY_PROHIBIT}:
raise ValueError("Invalid state payload.")

focus_value = facts[FOCUS_PRIMARY]
prohibit_value = policies[POLICY_PROHIBIT]
if focus_value is not None and not isinstance(focus_value, str):
raise ValueError("Invalid state payload.")
if not isinstance(prohibit_value, list) or any(
not isinstance(item, str) for item in prohibit_value
):
raise ValueError("Invalid state payload.")

return {
STATE_FACTS: {
FOCUS_PRIMARY: None if focus_value is None else _clean_fact_value(focus_value)
},
STATE_POLICIES: {POLICY_PROHIBIT: sorted(set(prohibit_value))},
STATE_VERSION: 1,
}


def _clarify(prompt: str) -> Decision:
return {
"kind": DecisionKind.CLARIFY,
Expand Down
160 changes: 160 additions & 0 deletions tests/test_engine.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import json

from context_compiler import create_engine
from context_compiler.engine import DecisionKind

Expand All @@ -9,6 +11,164 @@ def test_decision_kind_strenum_behavior() -> None:
assert DecisionKind(kind.value) is kind


def test_export_json_returns_complete_representation_of_state() -> None:
engine = create_engine()
engine.step("use Nord Stage 4")
engine.step("don't use docker")

payload = engine.export_json()
assert json.loads(payload) == {
"facts": {"focus.primary": "Nord Stage 4"},
"policies": {"prohibit": ["docker"]},
"version": 1,
}


def test_import_json_restores_state_exactly() -> None:
engine = create_engine()
engine.step("use Nord Stage 4")
engine.step("don't use docker")
snapshot = engine.export_json()

engine.step("clear state")
engine.import_json(snapshot)

assert engine.state == {
"facts": {"focus.primary": "Nord Stage 4"},
"policies": {"prohibit": ["docker"]},
"version": 1,
}


def test_export_import_round_trip_preserves_state() -> None:
source = create_engine()
source.step("use Nord Stage 4")
source.step("don't use docker")

target = create_engine()
target.import_json(source.export_json())

assert target.state == source.state


def test_imported_state_matches_live_subsequent_behavior() -> None:
live = create_engine()
live.step("use Nord Stage 4")
live.step("don't use parallel octaves")

imported = create_engine()
imported.import_json(live.export_json())

turns = [
"actually Nord Stage 3",
"don't use voice crossing",
"reset policies",
"allow docker",
]
for turn in turns:
assert imported.step(turn) == live.step(turn)
assert imported.state == live.state


def test_import_json_invalid_json_and_unsupported_version_are_rejected() -> None:
engine = create_engine()

try:
engine.import_json("{")
raise AssertionError("expected ValueError for invalid JSON")
except ValueError as exc:
assert "Invalid JSON payload" in str(exc)

try:
engine.import_json(
json.dumps(
{
"facts": {"focus.primary": None},
"policies": {"prohibit": []},
"version": 2,
}
)
)
raise AssertionError("expected ValueError for unsupported version")
except ValueError as exc:
assert "Unsupported state version" in str(exc)


def test_import_json_canonicalizes_duplicate_unsorted_prohibit_values() -> None:
engine = create_engine()
engine.import_json(
json.dumps(
{
"facts": {"focus.primary": None},
"policies": {"prohibit": ["kubernetes", "docker", "docker"]},
"version": 1,
}
)
)

assert engine.state == {
"facts": {"focus.primary": None},
"policies": {"prohibit": ["docker", "kubernetes"]},
"version": 1,
}


def test_import_json_sanitizes_fact_value_like_live_fact_write() -> None:
engine = create_engine()
engine.import_json(
json.dumps(
{
"facts": {"focus.primary": " MacBook M3` "},
"policies": {"prohibit": []},
"version": 1,
}
)
)

assert engine.state["facts"]["focus.primary"] == "MacBook M3'"


def test_import_json_clears_pending_clarification_state() -> None:
engine = create_engine()
decision = engine.step("no use docker")
assert decision["kind"] == "clarify"

engine.import_json(
json.dumps(
{
"facts": {"focus.primary": "Nord Stage 4"},
"policies": {"prohibit": ["kubernetes"]},
"version": 1,
}
)
)

decision_after_import = engine.step("yes")
assert decision_after_import["kind"] == "passthrough"
assert engine.state == {
"facts": {"focus.primary": "Nord Stage 4"},
"policies": {"prohibit": ["kubernetes"]},
"version": 1,
}


def test_imported_fact_state_restores_correction_behavior() -> None:
engine = create_engine()
engine.import_json(
json.dumps(
{
"facts": {"focus.primary": "Nord Stage 4"},
"policies": {"prohibit": []},
"version": 1,
}
)
)

decision = engine.step("actually Nord Stage 3")
assert decision["kind"] == "update"
assert engine.state["facts"]["focus.primary"] == "Nord Stage 3"


def test_directive_parsing_positive_negative_and_allow() -> None:
engine = create_engine()

Expand Down
Loading