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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "context-compiler"
version = "0.6.16"
version = "0.6.17"
description = "Deterministic conversational state engine for LLM applications."
readme = "README.md"
requires-python = ">=3.11"
Expand Down
11 changes: 11 additions & 0 deletions tests/fixtures/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,22 @@ This directory contains multiple fixture suites with different contracts.
## Fixture types

* [`conformance/`](conformance/) — core engine cross-language conformance contract.
Includes a small public API presence contract under `conformance/api/`.
* [`engine-regression/structured/`](engine-regression/structured/) — deterministic per-turn engine regression fixtures (including checkpoint snapshots).
* [`preprocessor/`](preprocessor/) — preprocessor heuristic and validation fixtures.

`conformance/` and `engine-regression/structured/` both cover engine behavior at different layers; preprocessor fixtures are intentionally separate from the core engine conformance contract.

## API contract fixture

[`conformance/api/public-api-v1.json`](conformance/api/public-api-v1.json) defines a small public API presence contract for the Python 0.6 surface that ports must expose.

Ports may sync this artifact with conformance fixtures.

Ports should check equivalent public exports and methods using language-appropriate names where casing differs.

Behavioral semantics remain covered by conformance and structured fixtures.

## Step fixtures

For [`conformance/step/`](conformance/step/):
Expand Down
29 changes: 29 additions & 0 deletions tests/fixtures/conformance/api/public-api-v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"id": "public-api-v1",
"kind": "api-contract",
"target": "context-compiler-ports",
"module": "context_compiler",
"required_exports": [
"create_engine",
"compile_transcript",
"get_premise_value",
"get_policy_items",
"TranscriptMessage",
"Transcript",
"ApplyResult"
],
"engine": {
"type": "Engine",
"required_members": [
"step",
"state",
"export_json",
"import_json",
"apply_transcript",
"export_checkpoint",
"import_checkpoint",
"export_checkpoint_json",
"import_checkpoint_json"
]
}
}
18 changes: 18 additions & 0 deletions tests/fixtures/preprocessor/public-api-v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"id": "experimental-preprocessor-public-api-v1",
"kind": "api-contract",
"module": "experimental.preprocessor",
"required_exports": [
"PRECOMPILE_OUTCOME_DIRECTIVE",
"PRECOMPILE_OUTCOME_NO_DIRECTIVE",
"PRECOMPILE_OUTCOME_UNKNOWN",
"PRECOMPILER_NO_DIRECTIVE_SENTINEL",
"PrecompileResult",
"PrecompileOutcome",
"parse_preprocessor_output",
"parse_precompiler_output",
"precompile_heuristic",
"render_prompt",
"validate_precompiler_output"
]
}
33 changes: 33 additions & 0 deletions tests/test_api_contract_fixture.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import json
from pathlib import Path

import context_compiler

_CONTRACT_PATH = (
Path(__file__).resolve().parent / "fixtures" / "conformance" / "api" / "public-api-v1.json"
)


def _load_contract() -> dict[str, object]:
return json.loads(_CONTRACT_PATH.read_text(encoding="utf-8"))


def test_api_contract_fixture_matches_python_public_surface() -> None:
contract = _load_contract()

assert contract["kind"] == "api-contract"
for name in contract["required_exports"]:
assert hasattr(context_compiler, name), name
assert name in context_compiler.__all__, name

engine = context_compiler.create_engine()
for name in contract["engine"]["required_members"]:
assert hasattr(engine, name), name


def test_api_contract_fixture_has_unique_entries() -> None:
contract = _load_contract()
required_exports = contract["required_exports"]
assert len(required_exports) == len(set(required_exports))
required_members = contract["engine"]["required_members"]
assert len(required_members) == len(set(required_members))
29 changes: 29 additions & 0 deletions tests/test_preprocessor_api_contract_fixture.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import json
from pathlib import Path

import experimental.preprocessor as preprocessor

_CONTRACT_PATH = (
Path(__file__).resolve().parent / "fixtures" / "preprocessor" / "public-api-v1.json"
)


def _load_contract() -> dict[str, object]:
return json.loads(_CONTRACT_PATH.read_text(encoding="utf-8"))


def test_preprocessor_api_contract_fixture_matches_public_surface() -> None:
contract = _load_contract()

assert contract["kind"] == "api-contract"

for name in contract["required_exports"]:
assert hasattr(preprocessor, name), name
assert name in preprocessor.__all__, name


def test_preprocessor_api_contract_fixture_has_unique_entries() -> None:
contract = _load_contract()

required_exports = contract["required_exports"]
assert len(required_exports) == len(set(required_exports))
6 changes: 5 additions & 1 deletion tests/test_preprocessor_conformance.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@


def _fixture_paths() -> list[Path]:
return sorted(_PREPROCESSOR_FIXTURES_DIR.glob("*.json"))
return sorted(
path
for path in _PREPROCESSOR_FIXTURES_DIR.glob("*.json")
if not path.name.startswith("public-api-")
)


def _load_fixture(path: Path) -> dict[str, object]:
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading