Skip to content

Phase 29.1 — SelfModel: Internal Representation of System Capabilities & Architecture #627

@web3guru888

Description

@web3guru888

Phase 29.1 — SelfModel: Internal Representation of System Capabilities & Architecture

Parent discussion: #626 (Phase 29 Planning)
Depends on: Phase 13 WorldModel (#383), Phase 16 PerformanceProfiler (#416)
Depended on by: 29.2 IntrospectionEngine, 29.5 SelfAwarenessOrchestrator


Overview

The SelfModel maintains an internal representation of the system's own capabilities, architectural topology, resource inventory, and competence boundaries. Inspired by Metzinger's (2003) phenomenal self-model theory — the system constructs a transparent model of itself that enables higher layers to reason about what it can and cannot do.


Data Structures

from enum import Enum, auto
from dataclasses import dataclass, field
from datetime import datetime
from typing import FrozenSet, Optional
import uuid

class SelfModelDomain(Enum):
    """Domains of self-knowledge."""
    ARCHITECTURE = auto()   # Module topology & connectivity
    CAPABILITY = auto()     # What the system can do
    RESOURCE = auto()       # CPU, memory, attention budgets
    COMPETENCE = auto()     # Proficiency scores per task type
    LIMITATION = auto()     # Known boundaries & failure modes

@dataclass(frozen=True)
class CapabilityProfile:
    """Profile of a single system capability."""
    domain: SelfModelDomain
    name: str
    proficiency_score: float   # 0.0 = no ability, 1.0 = expert
    latency_ms: float          # Expected execution time
    reliability: float         # Success rate 0.0-1.0
    dependencies: FrozenSet[str] = frozenset()
    last_assessed: datetime = field(default_factory=datetime.utcnow)

@dataclass(frozen=True)
class ResourceInventory:
    """Snapshot of available vs. consumed resources."""
    cpu_budget: float       # Total CPU units available
    memory_budget: float    # Total memory MB
    attention_budget: float # Attention slots (from Phase 28)
    used_cpu: float
    used_memory: float
    used_attention: float
    timestamp: datetime = field(default_factory=datetime.utcnow)

@dataclass(frozen=True)
class ArchitectureNode:
    """A single module in the architecture graph."""
    module_id: str
    module_type: str
    connections: FrozenSet[str] = frozenset()
    health_score: float = 1.0
    version: str = "0.0.0"

@dataclass(frozen=True)
class ArchitectureMap:
    """Complete system architecture as a directed graph."""
    nodes: tuple  # tuple[ArchitectureNode, ...]
    edges: tuple  # tuple[tuple[str, str], ...]  (source_id, target_id)
    created_at: datetime = field(default_factory=datetime.utcnow)

Protocol

from typing import Protocol, runtime_checkable

@runtime_checkable
class SelfModel(Protocol):
    """Internal representation of system capabilities & architecture."""

    async def get_capabilities(self, domain: SelfModelDomain) -> tuple[CapabilityProfile, ...]:
        """Return all capabilities in the given domain."""
        ...

    async def get_architecture(self) -> ArchitectureMap:
        """Return current architecture topology."""
        ...

    async def get_resources(self) -> ResourceInventory:
        """Return current resource inventory snapshot."""
        ...

    async def assess_competence(self, task_description: str) -> float:
        """Estimate competence (0-1) for the described task."""
        ...

    async def identify_limitations(self) -> tuple[str, ...]:
        """Return known limitations and failure modes."""
        ...

    async def update_model(self) -> None:
        """Trigger a full self-model refresh."""
        ...

Implementation — DynamicSelfModel

Key design decisions:

  • _capabilities: dict[SelfModelDomain, list[CapabilityProfile]] — mutable internal store, frozen on read
  • _architecture: ArchitectureMap — rebuilt on update_model() by querying ModuleRegistry (Phase 15) health endpoints
  • _resources: ResourceInventory — refreshed from PerformanceProfiler (Phase 16) and AttentionOrchestrator (Phase 28)
  • Auto-refresh: _refresh_interval (default 30s) triggers background update_model() via asyncio.create_task
  • WorldModel integration: Queries Phase 13 WorldModel for environment constraints that affect capabilities
  • Competence assessment: Fuzzy matching of task_description against capability names + dependency check; returns weighted average of matching proficiency scores
  • Limitation detection: Scans for capabilities with proficiency_score < 0.3 or reliability < 0.5; also checks resource utilization > 90%
  • Thread safety: asyncio.Lock on _capabilities and _architecture mutations

Null Implementation

class NullSelfModel:
    """No-op self-model for testing and graceful degradation."""
    async def get_capabilities(self, domain): return ()
    async def get_architecture(self): return ArchitectureMap(nodes=(), edges=())
    async def get_resources(self): return ResourceInventory(0,0,0,0,0,0)
    async def assess_competence(self, task_description): return 0.0
    async def identify_limitations(self): return ()
    async def update_model(self): pass

Factory

def make_self_model(
    *,
    world_model=None,
    performance_profiler=None,
    module_registry=None,
    attention_orchestrator=None,
    refresh_interval: float = 30.0,
    null: bool = False,
) -> SelfModel:
    if null:
        return NullSelfModel()
    return DynamicSelfModel(
        world_model=world_model,
        performance_profiler=performance_profiler,
        module_registry=module_registry,
        attention_orchestrator=attention_orchestrator,
        refresh_interval=refresh_interval,
    )

Prometheus Metrics

Metric Type Labels Description
self_model_assessments_total Counter domain Number of competence assessments
self_model_capability_score Gauge domain, name Current proficiency score per capability
self_model_resource_utilization Gauge resource_type Utilization ratio (0-1) per resource
self_model_staleness_seconds Gauge Time since last model refresh
self_model_limitations_detected Gauge Count of currently identified limitations

Test Targets (12)

  1. test_self_model_protocol_runtime_checkableisinstance(DynamicSelfModel(...), SelfModel)
  2. test_get_capabilities_filters_by_domain — returns only matching domain
  3. test_get_capabilities_returns_frozen_tuples — immutability check
  4. test_get_architecture_returns_valid_graph — all edge endpoints exist in nodes
  5. test_get_resources_snapshot_is_frozen — ResourceInventory is immutable
  6. test_assess_competence_returns_bounded_float — 0.0 ≤ result ≤ 1.0
  7. test_assess_competence_unknown_task_returns_low — unfamiliar task → score < 0.3
  8. test_identify_limitations_detects_low_proficiency — capabilities with score < 0.3 listed
  9. test_identify_limitations_detects_resource_exhaustion — utilization > 90% reported
  10. test_update_model_refreshes_all_components — architecture + capabilities + resources updated
  11. test_auto_refresh_fires_on_interval — mock clock advancement triggers update
  12. test_null_self_model_returns_defaults — NullSelfModel returns empty tuples / zeros

Metadata

Metadata

Assignees

No one assigned

    Labels

    phase-29Phase 29: Self-Awareness & Introspective Self-Modeling

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions