2026-05-18 20:33:45 +02:00
""" Service-readiness contracts, config, health, and conformance helpers. """
from __future__ import annotations
from dataclasses import dataclass , field
from typing import Any
2026-05-18 20:38:00 +02:00
from . adapters import (
AllowAllPolicyGateway ,
InMemoryMemoryEventLog ,
InMemoryMemoryGraphStore ,
InMemoryRuntimeRegistry ,
InMemorySemanticIndex ,
NoopContextPackageCompiler ,
RecordingAuditSink ,
)
2026-05-18 20:33:45 +02:00
from . models import Diagnostic , MemoryEvent , MemoryNode , PolicyDecision , ProfileIntent
from . runtime import PhaseMemoryRuntime
SERVICE_CONTRACT_SCHEMA = " phase_memory.service.contracts.v1 "
HEALTH_REPORT_SCHEMA = " phase_memory.health.report.v1 "
KONTEXTUAL_DELEGATION_SCHEMA = " phase_memory.kontextual.delegation.v1 "
SERVICE_OPERATIONS = {
" profile.plan " : { " request " : [ " profile " ] , " response " : " runtime_envelope " } ,
" graph.import " : { " request " : [ " graph " ] , " response " : " runtime_envelope " } ,
" graph.lifecycle.plan " : { " request " : [ " graph " , " parameters " ] , " response " : " runtime_envelope " } ,
" lifecycle.apply " : { " request " : [ " actions " , " review_record " ] , " response " : " runtime_envelope " } ,
" graph.activation.plan " : { " request " : [ " graph " , " budget " ] , " response " : " runtime_envelope " } ,
" package.compile " : { " request " : [ " selection " ] , " response " : " runtime_envelope " } ,
" audit.query " : { " request " : [ " filters " ] , " response " : " audit_events " } ,
" health.check " : { " request " : [ ] , " response " : " health_report " } ,
}
@dataclass ( frozen = True )
class RuntimeConfig :
local_store_path : str = " .phase-memory-local "
adapter_registry : dict [ str , str ] = field ( default_factory = lambda : { " graph_store " : " memory " , " event_log " : " memory " } )
policy_mode : str = " allow-all "
audit_sink_mode : str = " recording "
package_compiler_mode : str = " noop "
semantic_index_mode : str = " disabled "
dry_run_default : bool = True
trust_zone_labels : tuple [ str , . . . ] = ( " local " , )
@classmethod
def local_default ( cls ) - > " RuntimeConfig " :
return cls ( )
def diagnostics ( self ) - > tuple [ Diagnostic , . . . ] :
diagnostics : list [ Diagnostic ] = [ ]
if not self . local_store_path :
diagnostics . append ( Diagnostic ( " error " , " missing_store_path " , " Runtime config requires a local store path. " , " local_store_path " ) )
if self . policy_mode not in { " allow-all " , " external " } :
diagnostics . append ( Diagnostic ( " error " , " unsupported_policy_mode " , " Unsupported policy mode. " , " policy_mode " , { " policy_mode " : self . policy_mode } ) )
if self . semantic_index_mode not in { " disabled " , " external " } :
diagnostics . append ( Diagnostic ( " error " , " unsupported_semantic_index_mode " , " Unsupported semantic index mode. " , " semantic_index_mode " , { " semantic_index_mode " : self . semantic_index_mode } ) )
return tuple ( diagnostics )
def to_dict ( self ) - > dict [ str , Any ] :
return {
" local_store_path " : self . local_store_path ,
" adapter_registry " : dict ( self . adapter_registry ) ,
" policy_mode " : self . policy_mode ,
" audit_sink_mode " : self . audit_sink_mode ,
" package_compiler_mode " : self . package_compiler_mode ,
" semantic_index_mode " : self . semantic_index_mode ,
" dry_run_default " : self . dry_run_default ,
" trust_zone_labels " : list ( self . trust_zone_labels ) ,
}
def service_contracts ( ) - > dict [ str , Any ] :
return { " schema_version " : SERVICE_CONTRACT_SCHEMA , " operations " : SERVICE_OPERATIONS }
def runtime_from_config ( config : RuntimeConfig | None = None ) - > PhaseMemoryRuntime :
config = config or RuntimeConfig . local_default ( )
# First service-ready slice keeps adapters dependency-light. External
# adapter resolution belongs behind the registry in later deployments.
return PhaseMemoryRuntime ( )
def health_report ( runtime : PhaseMemoryRuntime , * , config : RuntimeConfig | None = None ) - > dict [ str , Any ] :
config = config or RuntimeConfig . local_default ( )
nodes = runtime . graph_store . list_nodes ( )
stale = [ node for node in nodes if node . lifecycle . value == " stale " ]
pending_review = [ node for node in nodes if node . lifecycle . value == " review_needed " ]
diagnostics = list ( config . diagnostics ( ) )
return {
" schema_version " : HEALTH_REPORT_SCHEMA ,
" ok " : not any ( diagnostic . severity == " error " for diagnostic in diagnostics ) ,
" adapters " : {
" graph_store " : runtime . graph_store . __class__ . __name__ ,
" event_log " : runtime . event_log . __class__ . __name__ ,
" policy_gateway " : runtime . policy_gateway . __class__ . __name__ ,
" audit_sink " : runtime . audit_sink . __class__ . __name__ ,
" package_compiler " : runtime . package_compiler . __class__ . __name__ ,
} ,
" config " : config . to_dict ( ) ,
" store " : {
" node_count " : len ( nodes ) ,
" stale_memory_count " : len ( stale ) ,
" pending_review_count " : len ( pending_review ) ,
} ,
" diagnostics " : [ diagnostic . to_dict ( ) for diagnostic in diagnostics ] ,
}
class LocalServiceRunner :
""" Minimal optional service runner shape without web framework dependency. """
def __init__ ( self , runtime : PhaseMemoryRuntime | None = None , config : RuntimeConfig | None = None ) - > None :
self . config = config or RuntimeConfig . local_default ( )
self . runtime = runtime or runtime_from_config ( self . config )
def handle ( self , operation : str , payload : dict [ str , Any ] | None = None ) - > dict [ str , Any ] :
payload = payload or { }
if operation == " health.check " :
return health_report ( self . runtime , config = self . config )
if operation == " profile.plan " :
return self . runtime . plan_profile ( payload [ " profile " ] , source_ref = payload . get ( " source_ref " , " service " ) )
if operation == " graph.import " :
return self . runtime . import_graph ( payload [ " graph " ] , source_ref = payload . get ( " source_ref " , " service " ) )
if operation == " graph.activation.plan " :
budget = payload . get ( " budget " , { } )
return self . runtime . plan_activation (
payload [ " graph " ] ,
max_items = int ( budget [ " max_items " ] ) ,
max_tokens = int ( budget [ " max_tokens " ] ) ,
profile_id = payload . get ( " profile_id " ) ,
)
raise ValueError ( f " Unsupported service operation: { operation } " )
def kontextual_delegation_envelope (
* ,
operation : str ,
graph_id : str = " " ,
profile_id : str = " " ,
policy_decision : dict [ str , Any ] | None = None ,
audit_ref : str = " " ,
) - > dict [ str , Any ] :
return {
" schema_version " : KONTEXTUAL_DELEGATION_SCHEMA ,
" operation " : operation ,
" phase_memory_owns " : [ " phase_policy " , " lifecycle_planning " , " activation_planning " ] ,
" kontextual_owns " : [ " durable_records " , " permission_aware_retrieval " , " long_lived_storage " ] ,
" graph_id " : graph_id ,
" profile_id " : profile_id ,
" policy_decision " : dict ( policy_decision or { } ) ,
" audit_ref " : audit_ref ,
" imports " : { " avoid_circular_imports " : True , " exchange " : " json_envelopes " } ,
}
def assert_graph_store_conformance ( store ) - > None :
profile = ProfileIntent ( profile_id = " conformance-profile " )
node = MemoryNode ( " node.conformance " , " decision " , " Conformance node " )
store . save_profile ( profile )
store . save_node ( node )
assert store . get_profile ( profile . profile_id ) . profile_id == profile . profile_id
assert store . get_node ( node . node_id ) . node_id == node . node_id
assert store . list_nodes ( kind = " decision " )
def assert_event_log_conformance ( log ) - > None :
event = MemoryEvent ( " event.conformance " , " recorded " )
log . append ( event )
assert log . list_events ( kind = " recorded " ) [ 0 ] . event_id == event . event_id
def assert_context_compiler_conformance ( compiler ) - > None :
response = compiler . compile_selection ( { " id " : " selection.conformance " , " nodes " : [ ] , " events " : [ ] } )
assert " package_id " in response or " package_ref " in response
def assert_policy_gateway_conformance ( gateway ) - > None :
decision = gateway . authorize ( action = " read " , resource = " node.conformance " )
assert isinstance ( decision , PolicyDecision )
def assert_audit_sink_conformance ( sink ) - > None :
receipt = sink . record ( { " operation " : " conformance " } )
assert receipt . get ( " recorded " ) is True
2026-05-18 20:38:00 +02:00
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 "
2026-05-18 20:33:45 +02:00
def default_conformance_adapters ( ) - > dict [ str , Any ] :
return {
" graph_store " : InMemoryMemoryGraphStore ( ) ,
" event_log " : InMemoryMemoryEventLog ( ) ,
" context_compiler " : NoopContextPackageCompiler ( ) ,
" policy_gateway " : AllowAllPolicyGateway ( ) ,
" audit_sink " : RecordingAuditSink ( ) ,
2026-05-18 20:38:00 +02:00
" semantic_index " : InMemorySemanticIndex ( ) ,
" runtime_registry " : InMemoryRuntimeRegistry ( ) ,
2026-05-18 20:33:45 +02:00
}