"""Layer 3 — Geometry Authority Kernel: implicit geometry, constraint solvers, feature lineage.""" from abc import ABC, abstractmethod from typing import Any from pydantic import BaseModel, Field class FeatureLineageEntry(BaseModel): """Single feature lineage entry: feature -> intent node, physics justification, process eligibility.""" feature_id: str = Field(...) intent_node_id: str = Field(...) physics_justification_ref: str | None = Field(default=None) process_eligible: bool = Field(default=False) class GeometryAuthorityInterface(ABC): """ Interface for implicit geometry, constraint solvers, feature lineage. Every geometric feature must map to intent node, physics justification, process eligibility. Orphan geometry is prohibited. """ @abstractmethod def add_feature( self, feature_id: str, intent_node_id: str, physics_justification_ref: str | None = None, process_eligible: bool = False, payload: dict[str, Any] | None = None, ) -> FeatureLineageEntry: """Register a feature with lineage; orphan (no intent) prohibited.""" ... @abstractmethod def get_lineage(self, feature_id: str) -> FeatureLineageEntry | None: """Return lineage for feature or None.""" ... @abstractmethod def validate_no_orphans(self) -> list[str]: """Return list of feature ids with no valid lineage (orphans); must be empty for MPC.""" ... class InMemoryGeometryKernel(GeometryAuthorityInterface): """In-memory geometry lineage model with orphan detection. Tracks both registered features (with lineage) and all known feature IDs. Features added via ``register_feature_id`` without a corresponding ``add_feature`` call are considered orphans. """ def __init__(self) -> None: self._lineage: dict[str, FeatureLineageEntry] = {} self._all_feature_ids: set[str] = set() def register_feature_id(self, feature_id: str) -> None: """Register a feature ID from the geometry model (may not have lineage yet).""" self._all_feature_ids.add(feature_id) def add_feature( self, feature_id: str, intent_node_id: str, physics_justification_ref: str | None = None, process_eligible: bool = False, payload: dict[str, Any] | None = None, ) -> FeatureLineageEntry: entry = FeatureLineageEntry( feature_id=feature_id, intent_node_id=intent_node_id, physics_justification_ref=physics_justification_ref, process_eligible=process_eligible, ) self._lineage[feature_id] = entry self._all_feature_ids.add(feature_id) return entry def get_lineage(self, feature_id: str) -> FeatureLineageEntry | None: return self._lineage.get(feature_id) def remove_feature(self, feature_id: str) -> bool: """Remove a feature and its lineage.""" removed = feature_id in self._lineage self._lineage.pop(feature_id, None) self._all_feature_ids.discard(feature_id) return removed def validate_no_orphans(self) -> list[str]: """Return feature IDs that exist but have no valid lineage.""" return [fid for fid in self._all_feature_ids if fid not in self._lineage] def list_features(self) -> list[str]: """Return all known feature IDs.""" return sorted(self._all_feature_ids) def count(self) -> int: """Return total feature count.""" return len(self._all_feature_ids)