from pathlib import Path import pytest pytestmark = [pytest.mark.integration, pytest.mark.markitect_tool] mkt = pytest.importorskip( "markitect_tool", reason="Install kontextual-engine[markdown] to run markitect-tool contract tests.", ) SAMPLE_MARKDOWN = """--- document_type: decision status: accepted policy: labels: [public] --- # Engine Boundary ## Context The engine needs Markdown-native structure without owning a Markdown parser. ## Decision Use markitect-tool as the syntax and deterministic operations layer. ## Consequences - Engine assets stay cross-format. - Markdown selectors stay Markitect-owned. """ def test_markitect_parser_returns_structured_markdown_document() -> None: document = mkt.parse_markdown(SAMPLE_MARKDOWN, source_path="docs/decision.md") serialized = document.to_dict() assert serialized["frontmatter"]["status"] == "accepted" assert serialized["source_path"] == "docs/decision.md" assert [heading["text"] for heading in serialized["headings"]] == [ "Engine Boundary", "Context", "Decision", "Consequences", ] assert any(section["heading"]["text"] == "Decision" for section in serialized["sections"]) def test_markitect_selectors_extract_source_grounded_markdown_units() -> None: document = mkt.parse_markdown(SAMPLE_MARKDOWN) matches = mkt.query_document(document, "sections[heading=Decision]") extracted = mkt.extract_document(document, "sections[heading=Decision]") assert len(matches) == 1 assert matches[0].kind == "section" assert matches[0].line is not None assert "deterministic operations layer" in matches[0].text assert extracted == [ "## Decision\n\nUse markitect-tool as the syntax and deterministic operations layer." ] def test_markitect_ops_resolve_includes_transform_and_return_provenance(tmp_path: Path) -> None: partial = tmp_path / "partial.md" partial.write_text( "# Included\n\n## Decision\n\nReuse Markitect operations.\n", encoding="utf-8", ) included = mkt.resolve_includes( '{{include:partial.md}}', base_dir=tmp_path, ) transformed = mkt.transform_markdown( included.markdown, set_frontmatter={"status": "draft"}, heading_delta=1, source_path="composed.md", ) assert included.included_paths == [str(partial.resolve())] assert included.provenance[0].operation == "include" assert included.provenance[0].target_path == str(partial.resolve()) assert "status: draft" in transformed.markdown assert "## Included" in transformed.markdown assert "### Decision" in transformed.markdown assert [event.operation for event in transformed.provenance] == [ "set_frontmatter", "shift_headings", ] def test_markitect_snapshot_identity_is_content_addressed_adapter_metadata(tmp_path: Path) -> None: source = tmp_path / "decision.md" source.write_text(SAMPLE_MARKDOWN, encoding="utf-8") first = mkt.snapshot_identity_for_file(source, parse_options={"profile": "default"}) second = mkt.snapshot_identity_for_file(source, parse_options={"profile": "default"}) changed = mkt.snapshot_identity_for_file(source, parse_options={"profile": "strict"}) assert first.snapshot_id == second.snapshot_id assert first.content_hash == second.content_hash assert first.parser == "markdown-it-py/commonmark" assert first.snapshot_id != changed.snapshot_id assert first.to_dict()["source_path"] == str(source) def test_markitect_context_packages_filter_by_local_policy(tmp_path: Path) -> None: public = tmp_path / "public.md" private = tmp_path / "private.md" public.write_text( "---\npolicy:\n labels: [public]\n---\n# Public\n\nVisible context.\n", encoding="utf-8", ) private.write_text( "---\npolicy:\n labels: [internal]\n---\n# Private\n\nHidden context.\n", encoding="utf-8", ) package = mkt.create_context_package_from_sources( "document", [public, private], root=tmp_path, namespace=mkt.MemoryNamespace(project="kontextual-engine", task="boundary"), budget=mkt.ContextBudget(max_items=5), ) gateway = mkt.LocalLabelPolicyGateway( { "id": "kontextual-engine-boundary", "subjects": { "reader": { "allowed_labels": ["public"], "allowed_actions": ["read", "activate"], } }, "default_subject": "reader", } ) activation = mkt.activate_context_package( package, policy_gateway=gateway, subject="reader", ) assert package.namespace.project == "kontextual-engine" assert len(activation.items) == 1 assert "Visible context" in activation.content assert "Hidden context" not in activation.content assert activation.policy["summary"]["denied"] == 1