Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 8, 2025

Pull Request: Extend SHA Metrics for Preservation Analysis

🎯 Intent

Enable quantitative assessment of structural preservation effectiveness during silence states. Adds deep telemetry for detection of degradation, reactivation timing, and collapse prediction across biomedical, cognitive, and social domains.

🔧 Changes

Type of Change:

  • New feature (coherence expansion)
  • Bug fix (stability improvement)
  • Performance optimization
  • Documentation update
  • Domain extension
  • Community pattern
  • Infrastructure/tooling

Implementation:

Added 4 helper functions to operators/metrics.py:

  • _compute_epi_variance() - σ(EPI) during silence (0.0 = perfect stability)
  • _compute_preservation_integrity() - Quality ratio [0,1] where <0.8 = failure
  • _compute_reactivation_readiness() - Multi-factor score: νf, EPI, duration, network support
  • _estimate_time_to_collapse() - Based on epi_drift_rate; returns ∞ if stable

Extended silence_metrics() return dict with 4 new fields while preserving all existing behavior.

Example Usage:

G.nodes[node]["preserved_epi"] = 0.5
G.nodes[node]["epi_history_during_silence"] = [0.5, 0.51, 0.49]
metrics = silence_metrics(G, node, vf_before=1.0, epi_before=0.5)

# New metrics available
metrics["epi_variance"]           # 0.008 (low = stable)
metrics["preservation_integrity"]  # 0.95 (high = good)
metrics["reactivation_readiness"]  # 0.72 (moderate)
metrics["time_to_collapse"]        # 600.0 or inf

🔬 Structural Impact

Operators Involved:
SHA (Silence)

Affected Invariants:
None violated. Extension only - adds telemetry without modifying operator semantics.

Metrics Impact:

  • C(t): Not directly affected
  • Si: Enables better Si trajectory analysis during silence
  • νf: Readiness metric factors νf residual for reactivation
  • Phase: Not directly affected

✅ Quality Checklist

Code Quality:

  • All tests pass locally
  • New tests added for new functionality (33 tests)
  • Type annotations complete (mypy passes)
  • Docstrings follow NumPy style guide
  • Code follows TNFR canonical conventions
  • .pyi stub files generated/updated

TNFR Canonical Requirements:

  • EPI changes only via structural operators (metrics are read-only)
  • Structural units (Hz_str) preserved
  • ΔNFR semantics maintained
  • Operator closure preserved
  • Phase verification explicit in couplings
  • Node birth/collapse conditions respected
  • Operational fractality maintained
  • Determinism/reproducibility ensured
  • Structural metrics exposed in telemetry
  • Domain neutrality maintained

Testing:

  • Monotonicity tests pass (coherence doesn't decrease)
  • Bifurcation tests pass (when applicable)
  • Propagation tests pass (resonance)
  • Multi-scale tests pass (fractality)
  • Reproducibility verified (seeds work)

Documentation:

  • CHANGELOG fragment added (docs/changelog.d/)
  • API documentation updated (if applicable)
  • Examples updated (if applicable)
  • README updated (if applicable)

Security (if applicable):

  • No vulnerabilities introduced
  • Security audit passed (make security-audit)
  • Dependency vulnerabilities addressed

🧪 Testing Evidence

Test Coverage:

tests/unit/operators/test_sha_extended_metrics.py::TestComputeEPIVariance (4 tests) ✓
tests/unit/operators/test_sha_extended_metrics.py::TestComputePreservationIntegrity (7 tests) ✓
tests/unit/operators/test_sha_extended_metrics.py::TestComputeReactivationReadiness (6 tests) ✓
tests/unit/operators/test_sha_extended_metrics.py::TestEstimateTimeToCollapse (5 tests) ✓
tests/unit/operators/test_sha_extended_metrics.py::TestSilenceMetricsExtended (8 tests) ✓
tests/unit/operators/test_sha_extended_metrics.py::TestSilenceMetricsIntegration (3 tests) ✓

33/33 passed | Backward compatibility: all existing tests pass

Health Metrics (if applicable):

Demo scenarios validate cross-domain applicability:
- Biomedical (sleep): preservation_integrity=1.0, epi_variance<0.01
- Cognitive (memory): preservation_integrity=1.0, time_to_collapse=∞
- Social (conflict): preservation_integrity=0.89, time_to_collapse=45

🔗 Related Issues

Closes #2714 (depends on latency state management - preserved_epi, silence_duration attributes)

📋 Additional Context

Design Decisions:

  • Helper functions prefixed with _ (internal use, not exported in __all__)
  • time_to_collapse returns float('inf') when no drift detected (not None)
  • preservation_integrity uses absolute value for preserved_epi to handle sign changes
  • Readiness score equally weights 4 factors (νf, EPI, duration, network) - tunable per domain

Cross-Domain Applicability:

  • Biomedical: HRV tracking, sleep consolidation, meditation states
  • Cognitive: Memory consolidation, incubation periods, learning retention
  • Social: Strategic pauses, conflict de-escalation, organizational stability

🎨 Visual Changes (if applicable)

N/A - Metrics only, no visualization changes


Reviewer Notes

Implementation is additive only. Zero breaking changes. All existing SHA behavior preserved. New metrics are optional - code using old metrics continues to work unchanged.

Original prompt

This section details on the original issue you should resolve

<issue_title>[SHA Metrics] Ampliar métricas de preservación estructural</issue_title>
<issue_description>## Contexto

Las métricas actuales de SHA en metrics.py son correctas pero básicas. Para análisis profundos de efectividad de preservación, se propone ampliarlas con tracking temporal, varianza e integridad estructural.

Métricas Actuales (Funcionales)

def silence_metrics(G, node, vf_before, epi_before) -> dict:
    return {
        "operator": "Silence",
        "glyph": "SHA",
        "vf_reduction": vf_before - vf_after,
        "vf_final": vf_after,
        "epi_preservation": abs(epi_after - epi_before),  # ✅ Correcto
        "epi_final": epi_after,
        "is_silent": vf_after < 0.1
    }

Métricas Extendidas Propuestas

1. Duración de Silencio (silence_duration)

Definición: Tiempo total en estado latente (en steps o tiempo estructural)

Utilidad:

  • Detectar silencios excesivos (riesgo de colapso nodal)
  • Analizar patrones de consolidación (memoria, aprendizaje)
  • Validar estrategias de pausa en simulaciones

Implementación:

"silence_duration": G.nodes[node].get("silence_duration", 0.0)

2. Varianza de EPI Durante Silencio (epi_variance)

Definición: Desviación estándar de EPI durante periodo de silencio

Utilidad:

  • Validar preservación efectiva (varianza ≈ 0)
  • Detectar interferencia externa durante silencio
  • Métrica de calidad de consolidación

Implementación:

def compute_epi_variance(G: TNFRGraph, node: NodeId) -> float:
    """Compute EPI variance during silence period."""
    epi_history = G.nodes[node].get("epi_history_during_silence", [])
    if len(epi_history) < 2:
        return 0.0
    return float(np.std(epi_history))

# En silence_metrics:
"epi_variance": compute_epi_variance(G, node)

3. Integridad de Preservación (preservation_integrity)

Definición: Ratio de cambio estructural relativo

[
\text{integrity} = 1 - \frac{|\text{EPI}{\text{after}} - \text{EPI}{\text{preserved}}|}{\text{EPI}_{\text{preserved}}}
]

Interpretación:

  • integrity = 1.0: Preservación perfecta
  • integrity < 0.95: Degradación significativa
  • integrity < 0.8: Fallo de preservación

Implementación:

preserved_epi = G.nodes[node].get("preserved_epi", epi_before)
if preserved_epi > 0:
    preservation_integrity = 1.0 - abs(epi_after - preserved_epi) / preserved_epi
else:
    preservation_integrity = 1.0

"preservation_integrity": max(0.0, preservation_integrity)

4. Capacidad de Reactivación (reactivation_readiness)

Definición: Score que evalúa si el nodo puede reactivarse efectivamente

Factores:

  • νf residual (debe ser recuperable)
  • EPI preservado (debe ser coherente)
  • Duración de silencio (no excesiva)
  • Conectividad de red (vecinos activos)

Implementación:

def compute_reactivation_readiness(G: TNFRGraph, node: NodeId) -> float:
    """
    Compute readiness score for reactivation from silence.
    
    Score in [0, 1]:
    - 1.0: Fully ready to reactivate
    - 0.5-0.8: Moderate readiness
    - < 0.3: Risky reactivation
    """
    vf = _get_node_attr(G, node, ALIAS_VF)
    epi = _get_node_attr(G, node, ALIAS_EPI)
    duration = G.nodes[node].get("silence_duration", 0.0)
    active_neighbors = sum(
        1 for n in G.neighbors(node)
        if _get_node_attr(G, n, ALIAS_VF) > 0.1
    )
    
    # Scoring components
    vf_score = min(vf / 0.5, 1.0)  # νf recuperable
    epi_score = min(epi / 0.3, 1.0)  # EPI coherente
    duration_score = 1.0 / (1.0 + duration * 0.1)  # Penaliza silencio largo
    network_score = min(active_neighbors / 3.0, 1.0)  # Soporte de red
    
    return (vf_score + epi_score + duration_score + network_score) / 4.0

5. Tiempo Hasta Colapso (time_to_collapse)

Definición: Estimación de cuánto tiempo puede mantenerse el silencio antes de colapso nodal

Modelo:
[
t_{\text{collapse}} \approx \frac{\text{EPI}_{\text{preserved}}}{|\text{DRIFT_RATE}|}
]

Donde DRIFT_RATE es la tasa de degradación estructural observada.

Actualización Completa de silence_metrics

def silence_metrics(
    G: TNFRGraph, node: NodeId, vf_before: float, epi_before: float
) -> dict[str, Any]:
    """
    SHA - Silence metrics: νf reduction, EPI preservation, duration tracking.
    
    Extended metrics for deep analysis of structural preservation effectiveness.
    """
    vf_after = _get_node_attr(G, node, ALIAS_VF)
    epi_after = _get_node_attr(G, node, ALIAS_EPI)
    preserved_epi = G.nodes[node].get("preserved_epi", epi_before)
    
    # Core metrics (existing)
    core = {
        "operator": "Silence",
        "glyph": "SHA",
        "vf_reduction": vf_before - vf_after,
        "vf_final": vf_after,
        "epi_preservation": abs(epi_after - epi_before),
        "epi_final": epi_after,
        "is_silent": vf...

</details>


> **Custom agent used: TNFR**
> TNFR Agent

- Fixes fermga/TNFR-Python-Engine#2716

<!-- START COPILOT CODING AGENT TIPS -->
---Let Copilot coding agent [set things up for you](https://github.com/fermga/TNFR-Python-Engine/issues/new?title=+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI self-assigned this Nov 8, 2025
@netlify
Copy link

netlify bot commented Nov 8, 2025

Deploy Preview for stunning-zabaione-f1f1ef failed. Why did it fail? →

Name Link
🔨 Latest commit 3d7edf3
🔍 Latest deploy log https://app.netlify.com/projects/stunning-zabaione-f1f1ef/deploys/690fa5a25e1a9d00083eded8

Copilot AI and others added 2 commits November 8, 2025 20:13
…e tests

Co-authored-by: fermga <203334638+fermga@users.noreply.github.com>
…ases

Co-authored-by: fermga <203334638+fermga@users.noreply.github.com>
Copilot AI changed the title [WIP] Add extended SHA preservation metrics [SHA Metrics] Extend silence metrics for structural preservation analysis Nov 8, 2025
Copilot AI requested a review from fermga November 8, 2025 20:22
@fermga fermga marked this pull request as ready for review November 8, 2025 20:23
Copilot AI review requested due to automatic review settings November 8, 2025 20:23
@fermga fermga merged commit 825c166 into main Nov 8, 2025
0 of 4 checks passed
@fermga fermga deleted the copilot/extend-sha-metrics branch November 8, 2025 20:23
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds extended metrics functionality to the SHA (Silence) operator to enable deep analysis of structural preservation effectiveness. The enhancements provide insights into EPI stability, preservation quality, reactivation readiness, and collapse risk prediction.

Key Changes

  • Four new helper functions to compute extended silence metrics (EPI variance, preservation integrity, reactivation readiness, time-to-collapse)
  • Enhanced silence_metrics() function to include extended metrics alongside core metrics
  • Comprehensive test suite covering all helper functions and integration scenarios
  • Demo file showcasing real-world use cases (biomedical, cognitive, social domains)

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/tnfr/operators/metrics.py Added four private helper functions and updated silence_metrics() to compute and return extended metrics for deeper preservation analysis
tests/unit/operators/test_sha_extended_metrics.py Comprehensive test suite with unit tests for each helper function, integration tests for the extended metrics, and domain-specific use case tests
examples/sha_extended_metrics_demo.py Interactive demo showcasing extended SHA metrics across biomedical (sleep consolidation), cognitive (memory consolidation), social (conflict pause), and failure detection scenarios

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1030 to +1033
_compute_epi_variance : EPI variance computation
_compute_preservation_integrity : Preservation quality metric
_compute_reactivation_readiness : Reactivation readiness score
_estimate_time_to_collapse : Collapse time estimation
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring references private helper functions in the "See Also" section. Since these functions are private (prefixed with _), they should not be part of the public API documentation.

If these functions are meant to remain private implementation details, remove them from the "See Also" section. If they should be part of the public API, remove the _ prefix and add them to __all__.

Suggested change
_compute_epi_variance : EPI variance computation
_compute_preservation_integrity : Preservation quality metric
_compute_reactivation_readiness : Reactivation readiness score
_estimate_time_to_collapse : Collapse time estimation

Copilot uses AI. Check for mistakes.
"preservation_integrity": (
_compute_preservation_integrity(preserved_epi, epi_after)
if preserved_epi is not None
else 1.0 - abs(epi_after - epi_before)
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fallback calculation for preservation_integrity when preserved_epi is None uses 1.0 - abs(epi_after - epi_before), which can produce negative values if the absolute difference is greater than 1.0. This differs from the behavior of _compute_preservation_integrity() which clamps negative values to 0.0.

For consistency, this should be:

max(0.0, 1.0 - abs(epi_after - epi_before))

This ensures the metric always stays in the [0, 1] range as documented.

Suggested change
else 1.0 - abs(epi_after - epi_before)
else max(0.0, 1.0 - abs(epi_after - epi_before))

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +65
_compute_epi_variance,
_compute_preservation_integrity,
_compute_reactivation_readiness,
_estimate_time_to_collapse,
)
from tnfr.alias import set_attr
from tnfr.constants.aliases import ALIAS_VF, ALIAS_EPI


class TestComputeEPIVariance:
"""Test _compute_epi_variance helper function."""

def test_no_history_returns_zero(self):
"""Empty history should return 0.0 variance."""
G, node = create_nfr("test", epi=0.5, vf=1.0)
# No epi_history_during_silence attribute
variance = _compute_epi_variance(G, node)
assert variance == 0.0

def test_single_value_returns_zero(self):
"""Single value in history should return 0.0 variance."""
G, node = create_nfr("test", epi=0.5, vf=1.0)
G.nodes[node]["epi_history_during_silence"] = [0.5]
variance = _compute_epi_variance(G, node)
assert variance == 0.0

def test_constant_values_returns_zero(self):
"""Constant values should return 0.0 variance."""
G, node = create_nfr("test", epi=0.5, vf=1.0)
G.nodes[node]["epi_history_during_silence"] = [0.5, 0.5, 0.5, 0.5]
variance = _compute_epi_variance(G, node)
assert variance == pytest.approx(0.0, abs=1e-10)

def test_varying_values_returns_positive_variance(self):
"""Varying values should return positive variance."""
G, node = create_nfr("test", epi=0.5, vf=1.0)
G.nodes[node]["epi_history_during_silence"] = [0.5, 0.6, 0.4, 0.55]
variance = _compute_epi_variance(G, node)
assert variance > 0.0
# Verify it's reasonable (should be around 0.07 for these values)
assert 0.05 < variance < 0.1


class TestComputePreservationIntegrity:
"""Test _compute_preservation_integrity helper function."""

Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test file imports private helper functions (prefixed with _) that are not exported in the __all__ list of src/tnfr/operators/metrics.py. This violates API design principles as private functions should not be part of the public API and should not be directly tested by importing them.

Consider either:

  1. Making these functions public by removing the _ prefix and adding them to __all__, OR
  2. Testing them indirectly through silence_metrics() which uses these functions internally

If these are intended to be internal implementation details, they should only be tested through the public API.

Suggested change
_compute_epi_variance,
_compute_preservation_integrity,
_compute_reactivation_readiness,
_estimate_time_to_collapse,
)
from tnfr.alias import set_attr
from tnfr.constants.aliases import ALIAS_VF, ALIAS_EPI
class TestComputeEPIVariance:
"""Test _compute_epi_variance helper function."""
def test_no_history_returns_zero(self):
"""Empty history should return 0.0 variance."""
G, node = create_nfr("test", epi=0.5, vf=1.0)
# No epi_history_during_silence attribute
variance = _compute_epi_variance(G, node)
assert variance == 0.0
def test_single_value_returns_zero(self):
"""Single value in history should return 0.0 variance."""
G, node = create_nfr("test", epi=0.5, vf=1.0)
G.nodes[node]["epi_history_during_silence"] = [0.5]
variance = _compute_epi_variance(G, node)
assert variance == 0.0
def test_constant_values_returns_zero(self):
"""Constant values should return 0.0 variance."""
G, node = create_nfr("test", epi=0.5, vf=1.0)
G.nodes[node]["epi_history_during_silence"] = [0.5, 0.5, 0.5, 0.5]
variance = _compute_epi_variance(G, node)
assert variance == pytest.approx(0.0, abs=1e-10)
def test_varying_values_returns_positive_variance(self):
"""Varying values should return positive variance."""
G, node = create_nfr("test", epi=0.5, vf=1.0)
G.nodes[node]["epi_history_during_silence"] = [0.5, 0.6, 0.4, 0.55]
variance = _compute_epi_variance(G, node)
assert variance > 0.0
# Verify it's reasonable (should be around 0.07 for these values)
assert 0.05 < variance < 0.1
class TestComputePreservationIntegrity:
"""Test _compute_preservation_integrity helper function."""
)
from tnfr.alias import set_attr
from tnfr.constants.aliases import ALIAS_VF, ALIAS_EPI

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SHA Operator] Implementar gestión de estado de latencia estructural

2 participants