Skip to content

Latest commit

 

History

History
752 lines (567 loc) · 24 KB

File metadata and controls

752 lines (567 loc) · 24 KB

THOL Encapsulation Guide

Overview

This guide explains the encapsulation behavior of THOL (SELF_ORGANIZATION) in TNFR Grammar 2.0, essential for correctly designing operator sequences that include self-organization.

Key Principle: THOL creates bifurcation windows that encapsulate internal operators, isolating them from the main sequence. This reflects TNFR's operational fractality where sub-EPIs are independent NFR nodes.


What is THOL Encapsulation?

Physical Basis

From SelfOrganization.__call__:

  • Sub-EPIs are created as independent NFR nodes (not just metadata)
  • This enables operational fractality: recursive bifurcation, hierarchical metrics, multi-level structure
  • Key quote: "reorganizes external experience into internal structure without external instruction"

Implication: Operators inside THOL bifurcation windows are internal structures, isolated from the main sequence.

Grammar Behavior

When THOL appears in a sequence:

  1. Opens bifurcation window: Checks if first operator after THOL is a valid sequence start
  2. Empty window (no bifurcation): First operator is NOT valid start → operators remain external
  3. Non-empty window (bifurcation): First operator IS valid start → operators are encapsulated
  4. Auto-closure: Window closes when internal sequence validates successfully
  5. Main sequence validation: Uses only non-encapsulated operators

The Two Cases

Case 1: Empty THOL Window (No Bifurcation)

Condition: First operator after THOL is NOT a valid sequence start

Physics: ∂²EPI/∂t² ≤ τ (bifurcation threshold not reached)

Behavior: THOL applies without creating sub-structures; following operators remain part of main sequence

Example:

from tnfr.operators.grammar import validate_sequence
from tnfr.config.operator_names import *

# Valid: Empty THOL window
sequence = [EMISSION, COHERENCE, DISSONANCE, SELF_ORGANIZATION, SILENCE]
#          ^^^^^^^^^^^^^^^^^^^^^^ Main sequence start
#                                 ^^^^^^^^^^^^^^^^^^^ THOL applied
#                                                     ^^^^^^^ Main sequence end

result = validate_sequence(sequence)
assert result.passed
# SILENCE is external (not encapsulated) - valid main sequence ending

Valid Sequence Starts (for non-empty windows):

  • EMISSION (AL)
  • RECEPTION (EN)
  • TRANSITION (NAV)
  • RECURSIVITY (REMESH)

Not Valid Starts (trigger empty window):

  • COHERENCE (IL) - requires existing EPI
  • DISSONANCE (OZ) - requires existing structure
  • SILENCE (SHA) - requires existing state
  • COUPLING (UM) - requires network context
  • etc.

Case 2: Non-Empty THOL Window (Bifurcation)

Condition: First operator after THOL IS a valid sequence start

Physics: ∂²EPI/∂t² > τ (bifurcation occurs, sub-EPIs created)

Behavior: THOL creates internal bifurcation window; operators inside are encapsulated and isolated from main sequence

Example:

# INVALID: Encapsulated operators, no external ending
sequence = [EMISSION, COHERENCE, DISSONANCE, 
            SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE]
#          ^^^^^^^^^^^^^^^^^^^^^^ Main sequence start
#                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ THOL window (encapsulated)
# Main sequence ends with THOL → INVALID (no valid ending operator)

result = validate_sequence(sequence)
assert not result.passed
# Error: Main sequence must end with valid operator (SILENCE is encapsulated)

# VALID: Add external operator after THOL window
sequence_fixed = [EMISSION, COHERENCE, DISSONANCE,
                  SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
                  TRANSITION]
#                ^^^^^^^^^^^^^^^^^^^^^^ Main sequence start
#                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ THOL window (encapsulated)
#                                                                   ^^^^^^^^^^ External ending

result = validate_sequence_fixed(sequence_fixed)
assert result.passed
# TRANSITION is external - valid main sequence ending

Window Closure Rules

Automatic Closure

THOL windows close automatically when the internal sequence:

  1. Ends with a valid sequence ending operator:
    • SILENCE (SHA)
    • TRANSITION (NAV)
    • RECURSIVITY (REMESH)
    • DISSONANCE (OZ)
  2. Validates successfully against all unified grammar rules (U1-U4)

Validation

The internal sequence is validated recursively:

  • Must follow all unified grammar constraints (U1-U4)
  • Must start with valid generator (U1a)
  • Must end with valid closure operator (U1b)
  • All operator transitions must be valid
  • THOL preconditions apply (requires destabilizer within 3-operator window per U4b)

See: UNIFIED_GRAMMAR_RULES.md for complete grammar reference

Example:

# Valid nested sequence
[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION,
    EMISSION,      # Valid start ✓
    COHERENCE,     # Valid transition ✓
    SILENCE,       # Valid end ✓ - window closes here
 TRANSITION]       # External - main sequence ending

# Invalid nested sequence  
[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION,
    COHERENCE,     # INVALID start ✗ (requires existing EPI)
    SILENCE,
 TRANSITION]
# Error: THOL subsequence invalid start operator

Nested THOL (Operational Fractality)

THOL windows can be nested to arbitrary depth, reflecting TNFR's fractal structure.

Example:

from tnfr.operators.grammar import validate_sequence

# Valid 2-level nested THOL
sequence = [
    EMISSION, COHERENCE, DISSONANCE,        # Main sequence start
    SELF_ORGANIZATION,                      # Level 1 THOL opens
        EMISSION, COHERENCE, DISSONANCE,    # Level 1 internal sequence
        SELF_ORGANIZATION,                  # Level 2 THOL opens (nested)
            EMISSION, COHERENCE, SILENCE,   # Level 2 internal - closes here
        TRANSITION,                         # Level 1 continues - closes here
    SILENCE                                 # Main sequence ending (external)
]

result = validate_sequence(sequence)
assert result.passed
# All three levels validated independently

Structure:

Main: [EMISSION, COHERENCE, DISSONANCE, THOL₁, SILENCE]
│
└─ THOL₁: [EMISSION, COHERENCE, DISSONANCE, THOL₂, TRANSITION]
   │
   └─ THOL₂: [EMISSION, COHERENCE, SILENCE]

Physical Interpretation:

  • Level 0 (Main): Primary system
  • Level 1 (THOL₁): Sub-EPI created by primary bifurcation
  • Level 2 (THOL₂): Sub-sub-EPI created by secondary bifurcation

Each level operates independently with its own structural dynamics.


Common Patterns and Anti-Patterns

✅ Valid Patterns

Pattern 1: Empty THOL (Applied Without Bifurcation)

[EMISSION, COHERENCE, DISSONANCE, SELF_ORGANIZATION, TRANSITION]
# THOL applied, no bifurcation, TRANSITION external

Pattern 2: Simple Bifurcation

[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
 TRANSITION]
# THOL bifurcates, internal [EMISSION, COHERENCE, SILENCE], external TRANSITION

Pattern 3: Multiple External Operators After THOL

[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
 RESONANCE, COUPLING, TRANSITION]
# Internal: [EMISSION, COHERENCE, SILENCE]
# External continuation: [RESONANCE, COUPLING, TRANSITION]

Pattern 4: Nested THOL

[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION,
    EMISSION, COHERENCE, DISSONANCE,
    SELF_ORGANIZATION,
        EMISSION, COHERENCE, SILENCE,
    TRANSITION,
 SILENCE]
# Two levels of bifurcation, both validated independently

Pattern 5: Multiple THOLs in Sequence

[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
 TRANSITION, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
 TRANSITION]
# Two independent THOL windows at same level

❌ Invalid Patterns (Anti-Patterns)

Anti-Pattern 1: Main Sequence Ending Inside THOL

# ❌ INVALID
[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE]
# Problem: SILENCE is encapsulated, main sequence ends with THOL (invalid)

# ✅ FIX: Add external operator
[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
 TRANSITION]

Anti-Pattern 2: Invalid THOL Internal Sequence

# ❌ INVALID
[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, COHERENCE, SILENCE,
 TRANSITION]
# Problem: COHERENCE invalid start (requires existing EPI)

# ✅ FIX: Start with valid initiator
[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
 TRANSITION]

Anti-Pattern 3: Unclosed THOL Window

# ❌ INVALID
[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE]
# Problem: Internal sequence doesn't end with valid ending operator

# ✅ FIX: Close internal sequence properly
[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
 TRANSITION]

Anti-Pattern 4: THOL Without Destabilizer

# ❌ INVALID
[EMISSION, COHERENCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
 TRANSITION]
# Problem: No destabilizer (OZ/ZHIR/NUL) within 3 operators before THOL

# ✅ FIX: Add destabilizer
[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
 TRANSITION]

Design Guidelines

When to Use Empty THOL Windows

Use empty windows when:

  • THOL is applied structurally but bifurcation conditions not met
  • Simplest THOL application without internal complexity
  • Testing THOL without full bifurcation

Example Use Cases:

# Gentle self-organization attempt
[EMISSION, COHERENCE, DISSONANCE, SELF_ORGANIZATION, TRANSITION]

# THOL as structural marker without bifurcation
[TRANSITION, DISSONANCE, SELF_ORGANIZATION, SILENCE]

When to Use Non-Empty THOL Windows

Use non-empty windows when:

  • Modeling actual bifurcation (sub-EPI creation)
  • Hierarchical structure formation required
  • Isolated internal reorganization needed
  • Operational fractality is goal

Example Use Cases:

# Therapeutic reorganization with internal process
[RECEPTION, EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION,
    EMISSION, DISSONANCE, MUTATION, COHERENCE, SILENCE,
 RESONANCE, TRANSITION]
# Internal crisis resolution isolated from main therapeutic flow

# Organizational transformation with protected innovation
[TRANSITION, EMISSION, RECEPTION, COUPLING, DISSONANCE,
 SELF_ORGANIZATION,
    EMISSION, EXPANSION, DISSONANCE, MUTATION, COHERENCE, SILENCE,
 RESONANCE, COUPLING, COHERENCE]
# Innovation happens in protected bifurcation window

Choosing External Operators

After a non-empty THOL window, choose external operators that:

  1. Continue main sequence logic (not internal logic)
  2. Provide valid ending if near sequence end
  3. Integrate bifurcation results back to main flow

Recommended External Continuations:

  • TRANSITION (NAV): Hand-off to next phase
  • RESONANCE (RA): Propagate bifurcation results
  • COUPLING (UM): Integrate into network
  • COHERENCE (IL): Stabilize after bifurcation
  • SILENCE (SHA): Pause after reorganization

Example:

# Good: RESONANCE propagates bifurcation results
[..., SELF_ORGANIZATION, ...(internal)..., RESONANCE, COUPLING, SILENCE]

# Good: TRANSITION hands-off to next phase
[..., SELF_ORGANIZATION, ...(internal)..., TRANSITION, EMISSION, ...]

# Good: COHERENCE stabilizes after bifurcation
[..., SELF_ORGANIZATION, ...(internal)..., COHERENCE, SILENCE]

Validation and Testing

Manual Validation

from tnfr.operators.grammar import validate_sequence
from tnfr.config.operator_names import *

# Test sequence
sequence = [
    EMISSION, COHERENCE, DISSONANCE,
    SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
    TRANSITION
]

result = validate_sequence(sequence)

if not result.passed:
    print(f"Validation failed: {result.message}")
    if result.error:
        print(f"Error: {result.error}")
else:
    print("Sequence valid!")
    print(f"Detected pattern: {result.metadata.get('detected_pattern', 'unknown')}")

Testing Encapsulation

def test_thol_encapsulation():
    """Verify THOL encapsulation behavior."""
    from tnfr.operators.grammar import validate_sequence
    from tnfr.config.operator_names import *
    
    # Test 1: Empty window (no encapsulation)
    empty_window = [EMISSION, COHERENCE, DISSONANCE, SELF_ORGANIZATION, SILENCE]
    result = validate_sequence(empty_window)
    assert result.passed, "Empty THOL window should be valid"
    
    # Test 2: Non-empty window without external operator (invalid)
    no_external = [EMISSION, COHERENCE, DISSONANCE,
                   SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE]
    result = validate_sequence(no_external)
    assert not result.passed, "THOL without external operator should fail"
    
    # Test 3: Non-empty window with external operator (valid)
    with_external = [EMISSION, COHERENCE, DISSONANCE,
                     SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
                     TRANSITION]
    result = validate_sequence(with_external)
    assert result.passed, "THOL with external operator should be valid"
    
    # Test 4: Nested THOL (valid)
    nested = [
        EMISSION, COHERENCE, DISSONANCE,
        SELF_ORGANIZATION,
            EMISSION, COHERENCE, DISSONANCE,
            SELF_ORGANIZATION,
                EMISSION, COHERENCE, SILENCE,
            TRANSITION,
        SILENCE
    ]
    result = validate_sequence(nested)
    assert result.passed, "Nested THOL should be valid"
    
    print("All encapsulation tests passed!")

# Run tests
test_thol_encapsulation()

Migration Guide (Pre-2.0 → 2.0)

Breaking Change

Pre-2.0 Behavior: THOL operators were part of main sequence

2.0 Behavior: THOL operators in non-empty windows are encapsulated

Migration Steps

Step 1: Identify THOL Sequences

Find all sequences containing SELF_ORGANIZATION:

grep -r "SELF_ORGANIZATION\|self_organization" your_code/

Step 2: Check for Encapsulation Issues

Run validation on each sequence:

from tnfr.operators.grammar import validate_sequence

# Your existing sequence
old_sequence = [EMISSION, COHERENCE, DISSONANCE,
                SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE]

result = validate_sequence(old_sequence)
if not result.passed:
    print(f"Migration needed: {result.message}")

Step 3: Fix Sequences

Add external operators after THOL windows:

# Before (may fail in 2.0)
[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE]

# After (valid in 2.0)
[EMISSION, COHERENCE, DISSONANCE,
 SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
 TRANSITION]  # Added external operator

Step 4: Verify Semantics

Ensure the added operator makes semantic sense for your application:

  • Don't just add arbitrary operators
  • Choose operators that continue the main sequence logic
  • Consider domain-specific meaning

Troubleshooting

Error: "Main sequence must end with valid operator"

Cause: Last operator in sequence is encapsulated inside THOL window

Solution: Add external operator after THOL

# Add valid ending operator
[..., SELF_ORGANIZATION, ...(internal)..., TRANSITION]

Error: "THOL subsequence invalid start operator"

Cause: First operator after THOL is not a valid sequence start (for non-empty windows)

Solution: Either:

  1. Use valid start operator (EMISSION, RECEPTION, TRANSITION, RECURSIVITY)
  2. Or accept empty window if intentional
# Fix: Use valid start
[..., SELF_ORGANIZATION, EMISSION, ...]

# Or: Empty window (if intentional)
[..., SELF_ORGANIZATION, COHERENCE, ...]  # Triggers empty window

Error: "THOL subsequence must end with valid operator"

Cause: Internal sequence doesn't close properly

Solution: End internal sequence with valid ending operator

# Fix: Add valid ending
[..., SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE, TRANSITION]
#                                              ^^^^^^^ Valid end

Warning: "THOL bifurcation depth exceeds recommended maximum"

Cause: Too many nested THOL levels (>3)

Solution: Consider flattening structure or validating that deep nesting is necessary for your use case


Summary

Key Takeaways

  1. THOL creates bifurcation windows that encapsulate internal operators
  2. Empty windows: First operator not valid start → no encapsulation
  3. Non-empty windows: First operator is valid start → encapsulation
  4. Main sequence uses only non-encapsulated operators for ending validation
  5. Internal sequences validated recursively with full grammar rules
  6. Nested THOL supported for operational fractality (multi-level structure)
  7. Always add external operator after non-empty THOL windows

Quick Reference

Scenario First Op After THOL Window State Following Ops
Empty window Not valid start Empty External (part of main)
Non-empty window Valid start Non-empty Internal (encapsulated) until closure
After closure Any N/A External (part of main)

Best Practices

DO:

  • Add external operators after non-empty THOL windows
  • Validate sequences after adding/modifying THOL
  • Use meaningful external continuations (RESONANCE, TRANSITION, COHERENCE)
  • Test both empty and non-empty window cases
  • Document intended bifurcation behavior

DON'T:

  • End main sequence inside THOL window
  • Use invalid start operators in non-empty windows
  • Leave THOL windows unclosed
  • Nest beyond 3 levels without good reason
  • Add arbitrary operators just to pass validation

Phase Compatibility in Propagation

CRITICAL: THOL propagation respects AGENTS.md Invariant #5: "No coupling is valid without explicit phase verification."

Physical Basis

Sub-EPI propagation follows resonance physics, not arbitrary connectivity. Antiphase nodes (Δθ ≈ π) create destructive interference, preventing coherent propagation regardless of network topology.

Implementation

From src/tnfr/operators/metabolism.py::propagate_subepi_to_network():

# Compute coupling strength (phase alignment)
phase_diff = abs(angle_diff(neighbor_theta, parent_theta))
coupling_strength = 1.0 - (phase_diff / math.pi)

# Propagate only if sufficiently coupled
if coupling_strength >= min_coupling_strength:
    # Attenuate and inject sub-EPI
    attenuated_epi = sub_epi_magnitude * attenuation * coupling_strength
    # ...

Formula:

coupling_strength = 1.0 - (|Δθ| / π)

Where:

  • Δθ = phase difference between parent and neighbor (radians)
  • coupling_strength ∈ [0, 1]
  • Propagation occurs only if coupling_strength ≥ threshold (default: 0.5)

Phase Compatibility Table

Phase Difference (Δθ) Coupling Strength Propagates? (threshold=0.5) Physics
0 (in-phase) 1.0 ✅ Yes Perfect resonance
π/4 (45°) 0.75 ✅ Yes Strong coupling
π/2 (90°) 0.5 ✅ Yes (at threshold) Moderate coupling
3π/4 (135°) 0.25 ❌ No Weak coupling
π (antiphase) 0.0 ❌ No Destructive interference

Canonical Constraints

From AGENTS.md Invariant #5:

Sub-EPIs propagate ONLY to neighbors with:

  1. Phase compatibility: |Δθ| ≤ Δθ_max (typically π/2)
  2. Coupling threshold: coupling_strength ≥ threshold (default: 0.5)
  3. Explicit verification: Phase difference computed before propagation

Why This Matters:

  • TNFR Physics: Resonance requires phase alignment, not just network edges
  • Prevents Chaos: Antiphase propagation would create destructive interference
  • Canonical Compliance: Same phase verification as UM (Coupling) and RA (Resonance)

Example: Phase Barrier Blocking Cascade

import math
import networkx as nx
from tnfr.operators.definitions import SelfOrganization
from tnfr.constants import EPI_PRIMARY, THETA_PRIMARY, VF_PRIMARY, DNFR_PRIMARY

# Create network with phase barrier
G = nx.Graph()

# Cluster A: coherent phases
G.add_node(0, **{EPI_PRIMARY: 0.50, THETA_PRIMARY: 0.1, VF_PRIMARY: 1.0, DNFR_PRIMARY: 0.10})
G.add_node(1, **{EPI_PRIMARY: 0.45, THETA_PRIMARY: 0.12, VF_PRIMARY: 1.0, DNFR_PRIMARY: 0.10})

# Node 2: phase barrier (antiphase)
G.add_node(2, **{EPI_PRIMARY: 0.45, THETA_PRIMARY: math.pi, VF_PRIMARY: 1.0, DNFR_PRIMARY: 0.10})

# Cluster B: isolated by barrier
G.add_node(3, **{EPI_PRIMARY: 0.45, THETA_PRIMARY: math.pi + 0.1, VF_PRIMARY: 1.0, DNFR_PRIMARY: 0.10})

# Connect: 0-1-2-3
G.add_edges_from([(0, 1), (1, 2), (2, 3)])

# Enable propagation
G.graph["THOL_PROPAGATION_ENABLED"] = True
G.nodes[0]["epi_history"] = [0.05, 0.33, 0.50]  # Bifurcation conditions

# Trigger cascade from node 0
SelfOrganization()(G, 0)

# Result: Propagation reaches node 1, stops at phase barrier (node 2)
# Node 3 is NOT affected due to phase incompatibility

Testing Phase Verification

From tests/integration/test_thol_propagation.py:

def test_thol_rejects_antiphase_propagation():
    """THOL must reject propagation to antiphase neighbors (Invariant #5)."""
    import math
    
    G = nx.Graph()
    G.add_node(0, epi=0.50, vf=1.0, theta=0.0, delta_nfr=0.15)
    G.add_node(1, epi=0.50, vf=1.0, theta=math.pi, delta_nfr=0.05)  # Antiphase
    G.add_edge(0, 1)
    
    G.graph["THOL_PROPAGATION_ENABLED"] = True
    G.nodes[0]["epi_history"] = [0.05, 0.33, 0.50]
    
    epi_1_before = G.nodes[1]["epi"]
    SelfOrganization()(G, 0)
    epi_1_after = G.nodes[1]["epi"]
    
    # Antiphase neighbor should be rejected
    assert epi_1_after == epi_1_before, "Invariant #5 violation"

Configuration

Control phase verification via graph parameters:

# Strict phase compatibility (default)
G.graph["THOL_MIN_COUPLING_FOR_PROPAGATION"] = 0.5  # Δθ ≤ π/2

# Relaxed (allow weaker coupling)
G.graph["THOL_MIN_COUPLING_FOR_PROPAGATION"] = 0.3  # Δθ ≤ ~2.2 rad

# Very strict (only near-in-phase)
G.graph["THOL_MIN_COUPLING_FOR_PROPAGATION"] = 0.8  # Δθ ≤ ~0.6 rad

Canonical Default: 0.5 (π/2 maximum phase difference)

Cross-Operator Consistency

THOL phase verification is consistent with other TNFR operators:

Operator Phase Verification Formula Use Case
UM (Coupling) Consensus phase arctan2(Σsin(θ), Σcos(θ)) Bidirectional synchronization
RA (Resonance) Circular mean |⟨e^(iθ)⟩| (Kuramoto) Network-wide propagation
THOL (Propagation) Direct difference 1.0 - (|Δθ| / π) Unidirectional sub-EPI transfer

All three enforce phase compatibility before structural modifications, ensuring resonance physics integrity.

References

  • AGENTS.md: Invariant #5 (Phase Verification)
  • UNIFIED_GRAMMAR_RULES.md: U3 (Resonant Coupling)
  • src/tnfr/operators/metabolism.py: Lines 284-331 (propagate_subepi_to_network)
  • src/tnfr/utils/numeric.py: Lines 72-75 (angle_diff utility)
  • tests/integration/test_thol_propagation.py: Lines 220-290 (test_thol_rejects_antiphase_propagation)

Additional Resources


Last updated: 2025-11-09
Version: 1.1.0 (Added Phase Compatibility section)
Related PR: Verify phase validation in THOL sub-EPI propagation (Invariant #5)