generated from coulomb/repo-seed
Complete adapter conformance coverage
This commit is contained in:
@@ -56,8 +56,10 @@ The service module includes reusable conformance helpers for:
|
|||||||
- graph stores
|
- graph stores
|
||||||
- event logs
|
- event logs
|
||||||
- context package compilers
|
- context package compilers
|
||||||
|
- semantic indexes
|
||||||
- policy gateways
|
- policy gateways
|
||||||
- audit sinks
|
- audit sinks
|
||||||
|
- runtime registries
|
||||||
|
|
||||||
External adapters should pass these helpers before being wired into a runtime.
|
External adapters should pass these helpers before being wired into a runtime.
|
||||||
|
|
||||||
|
|||||||
@@ -260,6 +260,43 @@ class JsonlAuditSink:
|
|||||||
return {"recorded": True, "index": index, "event": stored}
|
return {"recorded": True, "index": index, "event": stored}
|
||||||
|
|
||||||
|
|
||||||
|
class InMemorySemanticIndex:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self._nodes_by_graph: dict[str, list[MemoryNode]] = {}
|
||||||
|
|
||||||
|
def upsert_nodes(self, nodes: list[MemoryNode]) -> dict[str, Any]:
|
||||||
|
for node in nodes:
|
||||||
|
graph_id = str(node.metadata.get("graph_id") or "local")
|
||||||
|
existing = [item for item in self._nodes_by_graph.get(graph_id, []) if item.node_id != node.node_id]
|
||||||
|
existing.append(node)
|
||||||
|
self._nodes_by_graph[graph_id] = sorted(existing, key=lambda item: item.node_id)
|
||||||
|
return {"upserted": len(nodes)}
|
||||||
|
|
||||||
|
def query(self, *, graph_id: str, query: str, limit: int = 10) -> list[dict[str, Any]]:
|
||||||
|
terms = {term.lower() for term in query.split() if term.strip()}
|
||||||
|
results: list[dict[str, Any]] = []
|
||||||
|
for node in self._nodes_by_graph.get(graph_id, []):
|
||||||
|
text = f"{node.kind} {node.text}".lower()
|
||||||
|
score = sum(1 for term in terms if term in text)
|
||||||
|
if score:
|
||||||
|
results.append({"id": node.node_id, "score": score, "kind": node.kind})
|
||||||
|
return sorted(results, key=lambda item: (-item["score"], item["id"]))[:limit]
|
||||||
|
|
||||||
|
|
||||||
|
class InMemoryRuntimeRegistry:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self._envelopes: dict[str, dict[str, Any]] = {}
|
||||||
|
|
||||||
|
def publish_runtime_envelope(self, envelope: dict[str, Any]) -> dict[str, Any]:
|
||||||
|
reference = str(envelope.get("operation_id") or envelope.get("id") or f"envelope:{len(self._envelopes)}")
|
||||||
|
stored = dict(envelope)
|
||||||
|
self._envelopes[reference] = stored
|
||||||
|
return {"published": True, "reference": reference, "envelope": stored}
|
||||||
|
|
||||||
|
def fetch_runtime_envelope(self, reference: str) -> dict[str, Any]:
|
||||||
|
return dict(self._envelopes[reference])
|
||||||
|
|
||||||
|
|
||||||
def _safe_name(identifier: str) -> str:
|
def _safe_name(identifier: str) -> str:
|
||||||
safe = "".join(char if char.isalnum() or char in ("-", "_", ".") else "_" for char in identifier)
|
safe = "".join(char if char.isalnum() or char in ("-", "_", ".") else "_" for char in identifier)
|
||||||
return safe or "anonymous"
|
return safe or "anonymous"
|
||||||
|
|||||||
@@ -5,7 +5,15 @@ from __future__ import annotations
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from .adapters import AllowAllPolicyGateway, InMemoryMemoryEventLog, InMemoryMemoryGraphStore, NoopContextPackageCompiler, RecordingAuditSink
|
from .adapters import (
|
||||||
|
AllowAllPolicyGateway,
|
||||||
|
InMemoryMemoryEventLog,
|
||||||
|
InMemoryMemoryGraphStore,
|
||||||
|
InMemoryRuntimeRegistry,
|
||||||
|
InMemorySemanticIndex,
|
||||||
|
NoopContextPackageCompiler,
|
||||||
|
RecordingAuditSink,
|
||||||
|
)
|
||||||
from .models import Diagnostic, MemoryEvent, MemoryNode, PolicyDecision, ProfileIntent
|
from .models import Diagnostic, MemoryEvent, MemoryNode, PolicyDecision, ProfileIntent
|
||||||
from .runtime import PhaseMemoryRuntime
|
from .runtime import PhaseMemoryRuntime
|
||||||
|
|
||||||
@@ -179,6 +187,22 @@ def assert_audit_sink_conformance(sink) -> None:
|
|||||||
assert receipt.get("recorded") is True
|
assert receipt.get("recorded") is True
|
||||||
|
|
||||||
|
|
||||||
|
def assert_semantic_index_conformance(index) -> None:
|
||||||
|
node = MemoryNode("node.semantic", "decision", "Conformance search target", metadata={"graph_id": "graph.conformance"})
|
||||||
|
receipt = index.upsert_nodes([node])
|
||||||
|
results = index.query(graph_id="graph.conformance", query="search target", limit=5)
|
||||||
|
assert receipt.get("upserted") == 1
|
||||||
|
assert results and results[0]["id"] == node.node_id
|
||||||
|
|
||||||
|
|
||||||
|
def assert_runtime_registry_conformance(registry) -> None:
|
||||||
|
envelope = {"operation_id": "op.conformance", "operation": "conformance"}
|
||||||
|
receipt = registry.publish_runtime_envelope(envelope)
|
||||||
|
fetched = registry.fetch_runtime_envelope(receipt["reference"])
|
||||||
|
assert receipt["published"] is True
|
||||||
|
assert fetched["operation_id"] == "op.conformance"
|
||||||
|
|
||||||
|
|
||||||
def default_conformance_adapters() -> dict[str, Any]:
|
def default_conformance_adapters() -> dict[str, Any]:
|
||||||
return {
|
return {
|
||||||
"graph_store": InMemoryMemoryGraphStore(),
|
"graph_store": InMemoryMemoryGraphStore(),
|
||||||
@@ -186,4 +210,6 @@ def default_conformance_adapters() -> dict[str, Any]:
|
|||||||
"context_compiler": NoopContextPackageCompiler(),
|
"context_compiler": NoopContextPackageCompiler(),
|
||||||
"policy_gateway": AllowAllPolicyGateway(),
|
"policy_gateway": AllowAllPolicyGateway(),
|
||||||
"audit_sink": RecordingAuditSink(),
|
"audit_sink": RecordingAuditSink(),
|
||||||
|
"semantic_index": InMemorySemanticIndex(),
|
||||||
|
"runtime_registry": InMemoryRuntimeRegistry(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ from phase_memory.service import (
|
|||||||
assert_event_log_conformance,
|
assert_event_log_conformance,
|
||||||
assert_graph_store_conformance,
|
assert_graph_store_conformance,
|
||||||
assert_policy_gateway_conformance,
|
assert_policy_gateway_conformance,
|
||||||
|
assert_runtime_registry_conformance,
|
||||||
|
assert_semantic_index_conformance,
|
||||||
default_conformance_adapters,
|
default_conformance_adapters,
|
||||||
health_report,
|
health_report,
|
||||||
kontextual_delegation_envelope,
|
kontextual_delegation_envelope,
|
||||||
@@ -53,6 +55,8 @@ def test_default_adapter_conformance_helpers() -> None:
|
|||||||
assert_context_compiler_conformance(adapters["context_compiler"])
|
assert_context_compiler_conformance(adapters["context_compiler"])
|
||||||
assert_policy_gateway_conformance(adapters["policy_gateway"])
|
assert_policy_gateway_conformance(adapters["policy_gateway"])
|
||||||
assert_audit_sink_conformance(adapters["audit_sink"])
|
assert_audit_sink_conformance(adapters["audit_sink"])
|
||||||
|
assert_semantic_index_conformance(adapters["semantic_index"])
|
||||||
|
assert_runtime_registry_conformance(adapters["runtime_registry"])
|
||||||
|
|
||||||
|
|
||||||
def test_kontextual_delegation_envelope_is_explicit() -> None:
|
def test_kontextual_delegation_envelope_is_explicit() -> None:
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ Implemented outputs:
|
|||||||
- Health reports expose adapter availability, config diagnostics, stale memory
|
- Health reports expose adapter availability, config diagnostics, stale memory
|
||||||
counts, pending review counts, and store counts.
|
counts, pending review counts, and store counts.
|
||||||
- Adapter conformance helpers cover graph stores, event logs, context package
|
- Adapter conformance helpers cover graph stores, event logs, context package
|
||||||
compilers, policy gateways, and audit sinks.
|
compilers, semantic indexes, policy gateways, audit sinks, and runtime
|
||||||
|
registries.
|
||||||
- `kontextual_delegation_envelope` documents the JSON boundary that avoids
|
- `kontextual_delegation_envelope` documents the JSON boundary that avoids
|
||||||
circular imports while preserving ownership between phase-memory and
|
circular imports while preserving ownership between phase-memory and
|
||||||
`kontextual-engine`.
|
`kontextual-engine`.
|
||||||
|
|||||||
Reference in New Issue
Block a user