Implement live-shaped readiness workplan

This commit is contained in:
2026-05-19 01:06:41 +02:00
parent 3a52b3df41
commit 635d999621
21 changed files with 1507 additions and 54 deletions

102
tests/fixtures/public-api-snapshot.json vendored Normal file
View File

@@ -0,0 +1,102 @@
{
"exports": [
"ADAPTER_PACK_MANIFEST_SCHEMA",
"ActivationPlan",
"Diagnostic",
"EVALUATION_REPORT_SCHEMA",
"ExternalAdapterPack",
"FakeExternalEventLog",
"FakeExternalGraphStore",
"FakeExternalPolicyGateway",
"FakeExternalSemanticIndex",
"FakeKontextualRuntimeRegistry",
"FakeMarkitectPackageCompiler",
"FakeTelemetryAuditSink",
"LifecycleAction",
"LifecycleActionKind",
"LifecycleRuleConfig",
"LifecycleState",
"LiveShapedKontextualEventLog",
"LiveShapedKontextualGraphStore",
"LiveShapedKontextualRuntimeRegistry",
"LiveShapedMarkitectPackageCompiler",
"LiveShapedPermissionSemanticIndex",
"LiveShapedPolicyGateway",
"LiveShapedTelemetryAuditSink",
"LocalMarkitectValidator",
"LocalServiceRunner",
"MARKITECT_PACKAGE_REQUEST_SCHEMA",
"MARKITECT_PACKAGE_RESPONSE_SCHEMA",
"MemoryEdge",
"MemoryEvent",
"MemoryGraph",
"MemoryKind",
"MemoryNode",
"MemoryOperation",
"MemoryPath",
"MemoryPathState",
"MemoryPhase",
"OptionalMarkitectValidator",
"POLICY_OPERATION_POINTS",
"PhaseMemoryRuntime",
"PhaseTransitionRule",
"PolicyDecision",
"ProfileExecutionPlan",
"ProfileIntent",
"READINESS_REPORT_SCHEMA",
"RetentionRule",
"ReviewDecision",
"ReviewRecord",
"RuntimeAdapterBundle",
"RuntimeConfig",
"SERVICE_BINDING_SCHEMA",
"ServiceBinding",
"ServiceResponse",
"WordCountTokenEstimator",
"abandon_path",
"activation_quality_report",
"adapter_pack_manifest",
"branch_path",
"compact_path",
"create_path",
"evaluation_threshold_report",
"fake_external_adapter_pack",
"fake_external_runtime_config",
"graph_from_markitect",
"health_report",
"live_shaped_adapter_pack",
"make_review_record",
"merge_path",
"package_request_from_selection",
"package_response_envelope",
"path_event",
"plan_activation",
"plan_compaction",
"plan_lifecycle_from_profile",
"plan_neighborhood_activation",
"plan_phase_transition",
"plan_phase_transitions_from_rules",
"plan_profile_execution",
"plan_refresh",
"plan_retention",
"plan_retention_from_rules",
"profile_from_markitect",
"resolve_runtime_adapters",
"retrieve_graph_neighborhood",
"runtime_from_config",
"select_event_path",
"service_binding_from_config",
"service_contracts",
"validate_adapter_pack_manifest"
],
"service_operations": [
"audit.query",
"graph.activation.plan",
"graph.import",
"graph.lifecycle.plan",
"health.check",
"lifecycle.apply",
"package.compile",
"profile.plan"
]
}

View File

@@ -0,0 +1,72 @@
from datetime import datetime, timezone
from phase_memory.lifecycle import plan_compaction
from phase_memory.models import MemoryNode
from phase_memory.runtime import PhaseMemoryRuntime
def test_audit_export_traces_policy_denial_package_compile_and_review_apply() -> None:
runtime = PhaseMemoryRuntime()
graph = {
"schema_version": "markitect.memory.graph.v1",
"id": "audit.graph",
"nodes": [
{
"id": "node.public",
"kind": "knowledge",
"text": "Public node.",
"policy": {"labels": ["public"], "trust_zone": "local"},
},
{
"id": "node.secret",
"kind": "knowledge",
"text": "Secret node.",
"policy": {"labels": ["restricted"], "secret": True, "trust_zone": "local"},
},
],
"edges": [],
"events": [],
}
activation = runtime.plan_activation(
graph,
max_items=3,
max_tokens=30,
policy_context={"denied_labels": ["restricted"], "secrets_allowed": False, "trust_zone": "local"},
)
runtime.compile_package(activation["data"]["package_request"]["selection"])
node = runtime.graph_store.save_node(MemoryNode("audit.review", "episode", "Review text"))
compact = plan_compaction([node])
runtime.apply_lifecycle_actions([compact])
runtime.apply_lifecycle_actions([compact], approval_marker="review:audit")
export = runtime.export_audit_events()
operations = [event["operation"] for event in export["batch"]["events"]]
assert export["valid"] is True
assert "graph.activation.plan" in operations
assert "package.compile" in operations
assert operations.count("lifecycle.apply") == 2
assert activation["data"]["policy_denials"][0]["id"] == "node.secret"
def test_audit_retention_plan_identifies_eligible_records() -> None:
runtime = PhaseMemoryRuntime()
runtime.audit_sink.record(
{
"schema_version": "phase_memory.audit.event.v1",
"operation_id": "op:old",
"operation": "manual",
"timestamp": "2026-01-01T00:00:00+00:00",
"subject": {"kind": "audit_events", "id": "old"},
"source": {"ref": "test"},
"dry_run": True,
"allowed": True,
}
)
plan = runtime.audit_retention_plan(retention_days=30, now=datetime(2026, 5, 19, tzinfo=timezone.utc))
assert plan["valid"] is True
assert plan["plan"]["eligible_operation_ids"] == ["op:old"]
assert plan["plan"]["eligible_count"] == 1

View File

@@ -4,6 +4,7 @@ from pathlib import Path
from phase_memory.adapters import InMemorySemanticIndex
from phase_memory.contracts import graph_from_markitect
from phase_memory.evaluation import EVALUATION_REPORT_SCHEMA, evaluation_threshold_report
from phase_memory.models import ActivationPlan, MemoryPath
from phase_memory.retrieval import activation_quality_report, select_event_path
from phase_memory.runtime import PhaseMemoryRuntime
@@ -85,6 +86,22 @@ def test_budget_path_and_semantic_hint_scenario_meets_quality_thresholds() -> No
assert report["explanation_coverage"] == 1.0
def test_evaluation_threshold_report_summarizes_all_scenarios() -> None:
data = json.loads((FIXTURES / "evaluation-scenarios.json").read_text(encoding="utf-8"))
report = evaluation_threshold_report(data)
assert report["schema_version"] == EVALUATION_REPORT_SCHEMA
assert report["valid"] is True
assert report["metrics"]["scenario_count"] == 3
assert report["metrics"]["policy_denial_count"] == 1
assert report["metrics"]["lifecycle_action_count"] >= 3
assert report["metrics"]["path_event_count"] == 1
assert report["metrics"]["semantic_hit_count"] == 1
assert report["metrics"]["budget_omission_count"] == 1
assert report["diagnostics"] == []
def _activation_plan(response):
data = response["data"]["activation_plan"]
return ActivationPlan(

View File

@@ -7,6 +7,7 @@ from phase_memory.external_adapters import (
adapter_pack_manifest,
fake_external_adapter_pack,
fake_external_runtime_config,
live_shaped_adapter_pack,
validate_adapter_pack_manifest,
)
from phase_memory.service import (
@@ -64,6 +65,7 @@ def test_adapter_pack_manifest_reports_missing_capabilities() -> None:
capabilities=tuple(capability for capability in pack.capabilities if capability != "telemetry.audit.fake"),
ownership_boundaries=pack.ownership_boundaries,
required_conformance=pack.required_conformance,
capability_requirements=pack.capability_requirements,
metadata=pack.metadata,
)
@@ -100,3 +102,32 @@ def test_external_runtime_config_resolves_supplied_fake_pack() -> None:
assert fetched["operation"] == "package.compile"
assert report["ok"] is True
assert report["adapters"]["package_compiler"] == "FakeMarkitectPackageCompiler"
def test_live_shaped_adapter_pack_uses_same_manifest_and_conformance_contract() -> None:
config = fake_external_runtime_config()
pack = live_shaped_adapter_pack()
manifest = adapter_pack_manifest(pack)
bundle = resolve_runtime_adapters(config, external_adapters=pack.adapters)
runtime = runtime_from_config(config, external_adapters=pack.adapters)
assert validate_adapter_pack_manifest(pack) == ()
assert manifest["metadata"]["network_required"] is False
assert manifest["adapters"]["package_compiler"]["required_capabilities"] == ["markitect.package.compile.live-shaped"]
assert not [diagnostic for diagnostic in bundle.diagnostics if diagnostic.severity == "error"]
envelope = runtime.compile_package(
{
"schema_version": "markitect.memory.selection.v1",
"id": "selection.live-shaped",
"nodes": ["decision.boundary"],
"events": [],
}
)
registry_receipt = bundle.runtime_registry.publish_runtime_envelope(envelope)
fetched = bundle.runtime_registry.fetch_runtime_envelope(registry_receipt["reference"])
export = runtime.export_audit_events({"operation": "package.compile"})
assert envelope["data"]["package_response"]["package_ref"].startswith("markitect-live-shaped:")
assert fetched["operation"] == "package.compile"
assert export["batch"]["retention"]["mode"] == "live_shaped_telemetry"

View File

@@ -1,7 +1,7 @@
import json
from pathlib import Path
from phase_memory.adapters import FileBackedMemoryGraphStore, JsonlAuditSink, JsonlMemoryEventLog
from phase_memory.adapters import FileBackedMemoryGraphStore, JsonlAuditSink, JsonlMemoryEventLog, LOCAL_STORE_SCHEMA
from phase_memory.lifecycle import plan_compaction, plan_retention
from phase_memory.models import LifecycleAction, LifecycleActionKind, LifecycleState, MemoryEdge, MemoryEvent, MemoryNode
from phase_memory.paths import abandon_path, branch_path, create_path, merge_path, path_event
@@ -112,6 +112,55 @@ def test_file_backed_store_reports_migration_needs_and_uses_atomic_json_writes(t
assert not list(tmp_path.rglob("*.tmp"))
def test_local_store_migration_apply_updates_metadata_and_audits(tmp_path) -> None:
store = FileBackedMemoryGraphStore(tmp_path)
runtime = PhaseMemoryRuntime(graph_store=store, event_log=JsonlMemoryEventLog(tmp_path / "events.jsonl"))
(tmp_path / "phase-memory.json").write_text(
json.dumps(
{
"schema_version": "phase_memory.local_store.v0",
"planned_migrations": ["v0-to-v1"],
}
),
encoding="utf-8",
)
planned = runtime.plan_store_migration(source_ref=str(tmp_path))
applied = runtime.apply_store_migration(planned["data"]["migration_plan"], actor="pytest", source_ref=str(tmp_path))
metadata = store.metadata()
audit = runtime.query_audit({"operation": "store.migration.apply", "dry_run": False})
assert planned["valid"] is True
assert [action["action"] for action in planned["data"]["migration_plan"]["actions"]] == [
"set_schema_version",
"complete_planned_migration",
]
assert applied["valid"] is True
assert applied["data"]["migration_result"]["changed"] is True
assert metadata["schema_version"] == LOCAL_STORE_SCHEMA
assert metadata["completed_migrations"] == ["v0-to-v1"]
assert metadata["last_migration"]["actor"] == "pytest"
assert audit["count"] == 1
def test_local_store_migration_noop_and_corrupt_metadata_paths(tmp_path) -> None:
store = FileBackedMemoryGraphStore(tmp_path)
runtime = PhaseMemoryRuntime(graph_store=store, event_log=JsonlMemoryEventLog(tmp_path / "events.jsonl"))
noop = runtime.apply_store_migration(source_ref=str(tmp_path))
assert noop["valid"] is True
assert noop["data"]["migration_result"]["changed"] is False
(tmp_path / "phase-memory.json").write_text("{not-json}\n", encoding="utf-8")
planned = runtime.plan_store_migration(source_ref=str(tmp_path))
failed = runtime.apply_store_migration(source_ref=str(tmp_path))
assert planned["valid"] is False
assert planned["diagnostics"][0]["code"] == "corrupt_store_metadata"
assert failed["valid"] is False
assert failed["data"]["migration_result"]["applied"] is False
def test_repair_diagnostics_distinguish_corrupt_store_records(tmp_path) -> None:
store = FileBackedMemoryGraphStore(tmp_path)
runtime = PhaseMemoryRuntime(graph_store=store, event_log=JsonlMemoryEventLog(tmp_path / "events.jsonl"))

21
tests/test_public_api.py Normal file
View File

@@ -0,0 +1,21 @@
import json
from pathlib import Path
import phase_memory
from phase_memory.service import LocalServiceRunner, SERVICE_OPERATIONS, service_contracts
FIXTURES = Path(__file__).parent / "fixtures"
def test_public_api_snapshot_is_explicit() -> None:
snapshot = json.loads((FIXTURES / "public-api-snapshot.json").read_text(encoding="utf-8"))
assert sorted(phase_memory.__all__) == snapshot["exports"]
assert sorted(SERVICE_OPERATIONS) == snapshot["service_operations"]
def test_service_contract_catalog_matches_local_runner_supported_operations() -> None:
declared = set(service_contracts()["operations"])
assert set(LocalServiceRunner.supported_operations()) == declared

View File

@@ -0,0 +1,58 @@
import json
from io import BytesIO
from phase_memory import LocalServiceRunner, ServiceBinding
from phase_memory.service_binding import READINESS_REPORT_SCHEMA
def test_service_binding_exposes_health_readiness_and_contracts_without_listener() -> None:
binding = ServiceBinding(LocalServiceRunner())
health = binding.route("GET", "/health")
ready = binding.route("GET", "/ready")
contracts = binding.route("GET", "/contracts")
assert health.status == 200
assert ready.status == 200
assert ready.body["schema_version"] == READINESS_REPORT_SCHEMA
assert ready.body["unsupported_operations"] == []
assert "package.compile" in contracts.body["operations"]
def test_service_binding_dispatches_operation_payloads() -> None:
binding = ServiceBinding(LocalServiceRunner())
selection = {
"schema_version": "markitect.memory.selection.v1",
"id": "binding.selection",
"nodes": [],
"events": [],
}
response = binding.route("POST", "/operations/package.compile", {"selection": selection})
assert response.status == 200
assert response.body["operation"] == "package.compile"
assert response.body["data"]["package_response"]["package_ref"] == "package:binding.selection"
def test_service_binding_wsgi_adapter_is_callable_without_starting_server() -> None:
binding = ServiceBinding(LocalServiceRunner())
app = binding.as_wsgi_app()
statuses: list[str] = []
headers: list[list[tuple[str, str]]] = []
payload = json.dumps({"operation": "health.check", "payload": {}}).encode("utf-8")
result = app(
{
"REQUEST_METHOD": "POST",
"PATH_INFO": "/operations",
"CONTENT_LENGTH": str(len(payload)),
"wsgi.input": BytesIO(payload),
},
lambda status, response_headers: (statuses.append(status), headers.append(response_headers)),
)
body = json.loads(b"".join(result).decode("utf-8"))
assert statuses == ["200 OK"]
assert body["schema_version"] == "phase_memory.health.report.v1"
assert ("content-type", "application/json") in headers[0]