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.
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.
When THOL appears in a sequence:
- Opens bifurcation window: Checks if first operator after THOL is a valid sequence start
- Empty window (no bifurcation): First operator is NOT valid start → operators remain external
- Non-empty window (bifurcation): First operator IS valid start → operators are encapsulated
- Auto-closure: Window closes when internal sequence validates successfully
- Main sequence validation: Uses only non-encapsulated operators
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 endingValid 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.
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 endingTHOL windows close automatically when the internal sequence:
- Ends with a valid sequence ending operator:
- SILENCE (SHA)
- TRANSITION (NAV)
- RECURSIVITY (REMESH)
- DISSONANCE (OZ)
- Validates successfully against all unified grammar rules (U1-U4)
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 operatorTHOL 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 independentlyStructure:
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.
[EMISSION, COHERENCE, DISSONANCE, SELF_ORGANIZATION, TRANSITION]
# THOL applied, no bifurcation, TRANSITION external[EMISSION, COHERENCE, DISSONANCE,
SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
TRANSITION]
# THOL bifurcates, internal [EMISSION, COHERENCE, SILENCE], external TRANSITION[EMISSION, COHERENCE, DISSONANCE,
SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
RESONANCE, COUPLING, TRANSITION]
# Internal: [EMISSION, COHERENCE, SILENCE]
# External continuation: [RESONANCE, COUPLING, TRANSITION][EMISSION, COHERENCE, DISSONANCE,
SELF_ORGANIZATION,
EMISSION, COHERENCE, DISSONANCE,
SELF_ORGANIZATION,
EMISSION, COHERENCE, SILENCE,
TRANSITION,
SILENCE]
# Two levels of bifurcation, both validated independently[EMISSION, COHERENCE, DISSONANCE,
SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
TRANSITION, DISSONANCE,
SELF_ORGANIZATION, EMISSION, COHERENCE, SILENCE,
TRANSITION]
# Two independent THOL windows at same level# ❌ 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]# ❌ 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]# ❌ 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]# ❌ 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]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]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 windowAfter a non-empty THOL window, choose external operators that:
- Continue main sequence logic (not internal logic)
- Provide valid ending if near sequence end
- 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]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')}")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()Pre-2.0 Behavior: THOL operators were part of main sequence
2.0 Behavior: THOL operators in non-empty windows are encapsulated
Find all sequences containing SELF_ORGANIZATION:
grep -r "SELF_ORGANIZATION\|self_organization" your_code/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}")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 operatorEnsure 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
Cause: Last operator in sequence is encapsulated inside THOL window
Solution: Add external operator after THOL
# Add valid ending operator
[..., SELF_ORGANIZATION, ...(internal)..., TRANSITION]Cause: First operator after THOL is not a valid sequence start (for non-empty windows)
Solution: Either:
- Use valid start operator (EMISSION, RECEPTION, TRANSITION, RECURSIVITY)
- Or accept empty window if intentional
# Fix: Use valid start
[..., SELF_ORGANIZATION, EMISSION, ...]
# Or: Empty window (if intentional)
[..., SELF_ORGANIZATION, COHERENCE, ...] # Triggers empty windowCause: 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 endCause: Too many nested THOL levels (>3)
Solution: Consider flattening structure or validating that deep nesting is necessary for your use case
- THOL creates bifurcation windows that encapsulate internal operators
- Empty windows: First operator not valid start → no encapsulation
- Non-empty windows: First operator is valid start → encapsulation
- Main sequence uses only non-encapsulated operators for ending validation
- Internal sequences validated recursively with full grammar rules
- Nested THOL supported for operational fractality (multi-level structure)
- Always add external operator after non-empty THOL windows
| 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) |
✅ 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
CRITICAL: THOL propagation respects AGENTS.md Invariant #5: "No coupling is valid without explicit phase verification."
Sub-EPI propagation follows resonance physics, not arbitrary connectivity. Antiphase nodes (Δθ ≈ π) create destructive interference, preventing coherent propagation regardless of network topology.
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 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 |
From AGENTS.md Invariant #5:
Sub-EPIs propagate ONLY to neighbors with:
- Phase compatibility:
|Δθ| ≤ Δθ_max(typically π/2) - Coupling threshold:
coupling_strength ≥ threshold(default: 0.5) - 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)
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 incompatibilityFrom 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"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 radCanonical Default: 0.5 (π/2 maximum phase difference)
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.
- 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)
- THOL_CONFIGURATION_REFERENCE.md: Complete THOL parameter reference with canonical constraints
- GLYPH_SEQUENCES_GUIDE.md: Complete operator sequence reference
- GRAMMAR_2_0_TESTING_SUMMARY.md: Grammar 2.0 validation rules
- TNFR.pdf: Theoretical foundations of operational fractality
- src/tnfr/operators/grammar.py: Implementation details
- AGENTS.md: TNFR invariants and canonical principles
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)