generated from coulomb/repo-seed
173 lines
6.0 KiB
Python
173 lines
6.0 KiB
Python
from pathlib import Path
|
|
|
|
import yaml
|
|
from click.testing import CliRunner
|
|
|
|
from markitect_tool.cli import main
|
|
from markitect_tool.memory import (
|
|
ContextBudget,
|
|
LocalContextPackageRegistry,
|
|
MemoryNamespace,
|
|
activate_context_package,
|
|
create_context_package_from_index,
|
|
create_context_package_from_manifest,
|
|
create_context_package_from_sources,
|
|
refresh_context_package,
|
|
)
|
|
from markitect_tool.policy import LocalLabelPolicyGateway
|
|
|
|
|
|
def test_create_context_package_from_sources_preserves_spans_and_summary(tmp_path: Path):
|
|
source = tmp_path / "doc.md"
|
|
source.write_text("# Doc\n\n## Decision\n\nUse local memory packages.\n", encoding="utf-8")
|
|
|
|
package = create_context_package_from_sources(
|
|
"sections[heading=Decision]",
|
|
[source],
|
|
root=tmp_path,
|
|
namespace=MemoryNamespace(project="markitect-tool", task="MKTT-WP-0008"),
|
|
budget=ContextBudget(max_items=1),
|
|
)
|
|
|
|
assert package.id.startswith("memory:package:")
|
|
assert package.namespace.project == "markitect-tool"
|
|
assert package.items[0].source.path == "doc.md"
|
|
assert package.items[0].source.unit_kind == "section"
|
|
assert "local memory packages" in package.items[0].text
|
|
assert package.summaries[0].name == "overview"
|
|
|
|
|
|
def test_local_context_registry_saves_loads_and_activates(tmp_path: Path):
|
|
source = tmp_path / "doc.md"
|
|
source.write_text("# Doc\n\n## Context\n\nReusable project facts.\n", encoding="utf-8")
|
|
package = create_context_package_from_sources("sections[heading=Context]", [source], root=tmp_path)
|
|
registry = LocalContextPackageRegistry(tmp_path)
|
|
|
|
saved_path = registry.save(package)
|
|
loaded = registry.load(package.id)
|
|
activation_id = registry.activate(package.id, "thread:test")
|
|
activation = registry.load_activation(activation_id)
|
|
|
|
assert saved_path.exists()
|
|
assert loaded.id == package.id
|
|
assert activation.status == "active"
|
|
assert "Reusable project facts" in activation.content
|
|
|
|
|
|
def test_activation_can_recheck_policy_and_drop_denied_items(tmp_path: Path):
|
|
public = tmp_path / "public.md"
|
|
private = tmp_path / "private.md"
|
|
public.write_text("---\npolicy:\n labels: [public]\n---\n# Public\n\nVisible.\n", encoding="utf-8")
|
|
private.write_text("---\npolicy:\n labels: [internal]\n---\n# Private\n\nHidden.\n", encoding="utf-8")
|
|
package = create_context_package_from_sources("document", [public, private], root=tmp_path)
|
|
gateway = LocalLabelPolicyGateway(
|
|
{
|
|
"id": "memory-test-policy",
|
|
"subjects": {
|
|
"reader": {
|
|
"allowed_labels": ["public"],
|
|
"allowed_actions": ["read"],
|
|
}
|
|
},
|
|
"default_subject": "reader",
|
|
}
|
|
)
|
|
|
|
activation = activate_context_package(package, policy_gateway=gateway, subject="reader")
|
|
|
|
assert len(activation.items) == 1
|
|
assert "Visible" in activation.content
|
|
assert "Hidden" not in activation.content
|
|
assert activation.policy["summary"]["denied"] == 1
|
|
|
|
|
|
def test_create_context_package_from_index_search_and_refresh(tmp_path: Path):
|
|
source = tmp_path / "doc.md"
|
|
source.write_text("# Doc\n\nSearchable memory fact.\n", encoding="utf-8")
|
|
runner = CliRunner()
|
|
indexed = runner.invoke(main, ["cache", "index", str(tmp_path), "--root", str(tmp_path)])
|
|
assert indexed.exit_code == 0
|
|
|
|
package = create_context_package_from_index("Searchable", root=tmp_path, search=True)
|
|
source.write_text("# Doc\n\nSearchable memory fact changed.\n", encoding="utf-8")
|
|
reindexed = runner.invoke(main, ["cache", "index", str(tmp_path), "--root", str(tmp_path)])
|
|
refreshed = refresh_context_package(package)
|
|
|
|
assert reindexed.exit_code == 0
|
|
assert package.items
|
|
assert "changed" in refreshed.items[0].text
|
|
assert refreshed.id == package.id
|
|
|
|
|
|
def test_create_context_package_from_manifest(tmp_path: Path):
|
|
source = tmp_path / "doc.md"
|
|
source.write_text("# Doc\n\n## Purpose\n\nManifest selected context.\n", encoding="utf-8")
|
|
manifest = tmp_path / "context.yaml"
|
|
manifest.write_text(
|
|
yaml.safe_dump(
|
|
{
|
|
"title": "Manifest package",
|
|
"namespace": {"project": "markitect-tool"},
|
|
"retrieval_recipes": [
|
|
{
|
|
"kind": "selector",
|
|
"query": "sections[heading=Purpose]",
|
|
"sources": ["doc.md"],
|
|
}
|
|
],
|
|
},
|
|
sort_keys=False,
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
package = create_context_package_from_manifest(manifest, root=tmp_path)
|
|
|
|
assert package.title == "Manifest package"
|
|
assert package.namespace.project == "markitect-tool"
|
|
assert "Manifest selected context" in package.items[0].text
|
|
|
|
|
|
def test_mkt_context_pack_activate_explain_and_deactivate(tmp_path: Path):
|
|
source = tmp_path / "doc.md"
|
|
source.write_text("# Doc\n\n## Decision\n\nUse explicit context packages.\n", encoding="utf-8")
|
|
runner = CliRunner()
|
|
|
|
packed = runner.invoke(
|
|
main,
|
|
[
|
|
"context",
|
|
"pack",
|
|
"sections[heading=Decision]",
|
|
"--source",
|
|
str(source),
|
|
"--root",
|
|
str(tmp_path),
|
|
"--format",
|
|
"json",
|
|
],
|
|
)
|
|
assert packed.exit_code == 0
|
|
package_id = yaml.safe_load(packed.output)["id"]
|
|
|
|
explained = runner.invoke(main, ["context", "explain", package_id, "--root", str(tmp_path)])
|
|
activated = runner.invoke(
|
|
main,
|
|
[
|
|
"context",
|
|
"activate",
|
|
package_id,
|
|
"--root",
|
|
str(tmp_path),
|
|
"--format",
|
|
"json",
|
|
],
|
|
)
|
|
activation_id = yaml.safe_load(activated.output)["id"]
|
|
deactivated = runner.invoke(main, ["context", "deactivate", activation_id, "--root", str(tmp_path)])
|
|
|
|
assert explained.exit_code == 0
|
|
assert "Use explicit context packages" in activated.output
|
|
assert deactivated.exit_code == 0
|
|
assert "inactive" in deactivated.output
|